├── .gitignore
├── Contact Editor
├── en.lproj
│ └── InfoPlist.strings
├── ViewController.h
├── CollectionViewController.h
├── AppDelegate.h
├── DetailViewController.h
├── ContactList.h
├── main.m
├── Contact Editor-Prefix.pch
├── Contact.h
├── ViewController.m
├── Images.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── LaunchImage.launchimage
│ │ └── Contents.json
├── Contact Editor-Info.plist
├── Base.lproj
│ ├── Main_iPad.storyboard
│ └── Main_iPhone.storyboard
├── DetailViewController.m
├── AppDelegate.m
├── ContactList.mm
├── CollectionViewController.m
└── Contact.m
├── Contact EditorTests
├── en.lproj
│ └── InfoPlist.strings
├── Contact EditorTests-Info.plist
└── Contact_EditorTests.m
└── Contact Editor.xcodeproj
├── project.xcworkspace
├── contents.xcworkspacedata
└── xcshareddata
│ └── Contact Editor.xccheckout
└── project.pbxproj
/.gitignore:
--------------------------------------------------------------------------------
1 | xcuserdata
2 |
--------------------------------------------------------------------------------
/Contact Editor/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Contact EditorTests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Contact Editor.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Contact Editor/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Contact Editor/CollectionViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionViewController.h
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CollectionViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Contact Editor/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Contact Editor/DetailViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.h
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class Contact;
12 |
13 |
14 |
15 | @interface DetailViewController : UITableViewController
16 |
17 | @property (nonatomic, strong) Contact *contact;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Contact Editor/ContactList.h:
--------------------------------------------------------------------------------
1 | //
2 | // ContactList.h
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 02/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 |
13 | @interface ContactList : NSObject
14 |
15 | + (instancetype)sharedContactList;
16 |
17 | @property (readonly, nonatomic, strong) NSMutableOrderedSet *contacts;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/Contact Editor/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "AppDelegate.h"
12 |
13 | int main(int argc, char * argv[])
14 | {
15 | @autoreleasepool {
16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/Contact Editor/Contact Editor-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | #import
15 | #import
16 | #endif
17 |
--------------------------------------------------------------------------------
/Contact Editor/Contact.h:
--------------------------------------------------------------------------------
1 | //
2 | // Contact.h
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 |
13 | @interface Contact : NSObject
14 |
15 | + (instancetype)contactWithRancomName;
16 |
17 | @property (nonatomic, copy) NSString *name;
18 | @property (nonatomic, copy) NSString *nickname;
19 | @property (nonatomic, copy) NSString *email;
20 | @property (nonatomic, copy) NSString *city;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/Contact Editor/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface ViewController ()
12 |
13 | @end
14 |
15 | @implementation ViewController
16 |
17 | - (void)viewDidLoad
18 | {
19 | [super viewDidLoad];
20 | // Do any additional setup after loading the view, typically from a nib.
21 | }
22 |
23 | - (void)didReceiveMemoryWarning
24 | {
25 | [super didReceiveMemoryWarning];
26 | // Dispose of any resources that can be recreated.
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Contact EditorTests/Contact EditorTests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | io.objc.${PRODUCT_NAME:rfc1034identifier}
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/Contact EditorTests/Contact_EditorTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // Contact_EditorTests.m
3 | // Contact EditorTests
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface Contact_EditorTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation Contact_EditorTests
16 |
17 | - (void)setUp
18 | {
19 | [super setUp];
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 | }
22 |
23 | - (void)tearDown
24 | {
25 | // Put teardown code here. This method is called after the invocation of each test method in the class.
26 | [super tearDown];
27 | }
28 |
29 | - (void)testExample
30 | {
31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__);
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/Contact Editor/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "40x40",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "60x60",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "ipad",
20 | "size" : "29x29",
21 | "scale" : "1x"
22 | },
23 | {
24 | "idiom" : "ipad",
25 | "size" : "29x29",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "ipad",
30 | "size" : "40x40",
31 | "scale" : "1x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "40x40",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "76x76",
41 | "scale" : "1x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "76x76",
46 | "scale" : "2x"
47 | }
48 | ],
49 | "info" : {
50 | "version" : 1,
51 | "author" : "xcode"
52 | }
53 | }
--------------------------------------------------------------------------------
/Contact Editor/Images.xcassets/LaunchImage.launchimage/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "orientation" : "portrait",
5 | "idiom" : "iphone",
6 | "extent" : "full-screen",
7 | "minimum-system-version" : "7.0",
8 | "scale" : "2x"
9 | },
10 | {
11 | "orientation" : "portrait",
12 | "idiom" : "iphone",
13 | "subtype" : "retina4",
14 | "extent" : "full-screen",
15 | "minimum-system-version" : "7.0",
16 | "scale" : "2x"
17 | },
18 | {
19 | "orientation" : "portrait",
20 | "idiom" : "ipad",
21 | "extent" : "full-screen",
22 | "minimum-system-version" : "7.0",
23 | "scale" : "1x"
24 | },
25 | {
26 | "orientation" : "landscape",
27 | "idiom" : "ipad",
28 | "extent" : "full-screen",
29 | "minimum-system-version" : "7.0",
30 | "scale" : "1x"
31 | },
32 | {
33 | "orientation" : "portrait",
34 | "idiom" : "ipad",
35 | "extent" : "full-screen",
36 | "minimum-system-version" : "7.0",
37 | "scale" : "2x"
38 | },
39 | {
40 | "orientation" : "landscape",
41 | "idiom" : "ipad",
42 | "extent" : "full-screen",
43 | "minimum-system-version" : "7.0",
44 | "scale" : "2x"
45 | }
46 | ],
47 | "info" : {
48 | "version" : 1,
49 | "author" : "xcode"
50 | }
51 | }
--------------------------------------------------------------------------------
/Contact Editor.xcodeproj/project.xcworkspace/xcshareddata/Contact Editor.xccheckout:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDESourceControlProjectFavoriteDictionaryKey
6 |
7 | IDESourceControlProjectIdentifier
8 | FB924164-1A0B-4A74-87F5-F84B1DBE8ADE
9 | IDESourceControlProjectName
10 | Contact Editor
11 | IDESourceControlProjectOriginsDictionary
12 |
13 | 41F54BE1-E16D-4BAE-9DF7-C99546CC59A6
14 | ssh://github.com/chriseidhof/objc.io.git
15 |
16 | IDESourceControlProjectPath
17 | Projects/Contact Editor/Contact Editor.xcodeproj/project.xcworkspace
18 | IDESourceControlProjectRelativeInstallPathDictionary
19 |
20 | 41F54BE1-E16D-4BAE-9DF7-C99546CC59A6
21 | ../../../..
22 |
23 | IDESourceControlProjectURL
24 | ssh://github.com/chriseidhof/objc.io.git
25 | IDESourceControlProjectVersion
26 | 110
27 | IDESourceControlProjectWCCIdentifier
28 | 41F54BE1-E16D-4BAE-9DF7-C99546CC59A6
29 | IDESourceControlProjectWCConfigurations
30 |
31 |
32 | IDESourceControlRepositoryExtensionIdentifierKey
33 | public.vcs.git
34 | IDESourceControlWCCIdentifierKey
35 | 41F54BE1-E16D-4BAE-9DF7-C99546CC59A6
36 | IDESourceControlWCCName
37 | objc
38 |
39 |
40 |
41 |
42 |
--------------------------------------------------------------------------------
/Contact Editor/Contact Editor-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | io.objc.${PRODUCT_NAME:rfc1034identifier}
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UIMainStoryboardFile
28 | Main_iPhone
29 | UIMainStoryboardFile~ipad
30 | Main_iPad
31 | UIRequiredDeviceCapabilities
32 |
33 | armv7
34 |
35 | UISupportedInterfaceOrientations
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationLandscapeLeft
39 | UIInterfaceOrientationLandscapeRight
40 |
41 | UISupportedInterfaceOrientations~ipad
42 |
43 | UIInterfaceOrientationPortrait
44 | UIInterfaceOrientationPortraitUpsideDown
45 | UIInterfaceOrientationLandscapeLeft
46 | UIInterfaceOrientationLandscapeRight
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/Contact Editor/Base.lproj/Main_iPad.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
--------------------------------------------------------------------------------
/Contact Editor/DetailViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // DetailViewController.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import "DetailViewController.h"
10 |
11 | #import "Contact.h"
12 |
13 |
14 |
15 | @interface DetailViewController ()
16 |
17 | @property (weak, nonatomic) IBOutlet UITextField *nameField;
18 | @property (weak, nonatomic) IBOutlet UITextField *nicknameField;
19 | @property (weak, nonatomic) IBOutlet UITextField *emailField;
20 | @property (weak, nonatomic) IBOutlet UITextField *cityField;
21 |
22 | @end
23 |
24 |
25 |
26 | @implementation DetailViewController
27 |
28 | - (void)viewWillAppear:(BOOL)animated;
29 | {
30 | [super viewWillAppear:animated];
31 | [self updateTextFields];
32 | }
33 |
34 | - (NSArray *)contactStringKeys;
35 | {
36 | return @[@"name", @"nickname", @"email", @"city"];
37 | }
38 |
39 | - (UITextField *)textFieldForModelKey:(NSString *)key;
40 | {
41 | return [self valueForKey:[key stringByAppendingString:@"Field"]];
42 | }
43 |
44 | - (void)setContact:(Contact *)contact
45 | {
46 | _contact = contact;
47 | [self updateTextFields];
48 | }
49 |
50 | - (void)updateTextFields;
51 | {
52 | for (NSString *key in self.contactStringKeys) {
53 | [self textFieldForModelKey:key].text = [self.contact valueForKey:key];
54 | }
55 | }
56 |
57 | - (IBAction)fieldEditingDidEnd:(UITextField *)sender
58 | {
59 | for (NSString *key in self.contactStringKeys) {
60 | UITextField *field = [self textFieldForModelKey:key];
61 | if (field == sender) {
62 | id value = sender.text;
63 | NSError *error = nil;
64 | if ([self.contact validateValue:&value forKey:key error:&error]) {
65 | [self.contact setValue:value forKey:key];
66 | } else {
67 | // Should present this to the user:
68 | NSLog(@"Error: %@", error);
69 | }
70 | sender.text = value;
71 | break;
72 | }
73 | }
74 | }
75 |
76 | @end
77 |
--------------------------------------------------------------------------------
/Contact Editor/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @implementation AppDelegate
12 |
13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
14 | {
15 | // Override point for customization after application launch.
16 | return YES;
17 | }
18 |
19 | - (void)applicationWillResignActive:(UIApplication *)application
20 | {
21 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
22 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
23 | }
24 |
25 | - (void)applicationDidEnterBackground:(UIApplication *)application
26 | {
27 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
28 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
29 | }
30 |
31 | - (void)applicationWillEnterForeground:(UIApplication *)application
32 | {
33 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
34 | }
35 |
36 | - (void)applicationDidBecomeActive:(UIApplication *)application
37 | {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application
42 | {
43 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Contact Editor/ContactList.mm:
--------------------------------------------------------------------------------
1 | //
2 | // ContactList.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 02/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import "ContactList.h"
10 |
11 | #import "Contact.h"
12 | #import
13 | #import
14 |
15 |
16 |
17 | @implementation ContactList
18 | {
19 | std::vector<__strong Contact *> _contacts;
20 | }
21 |
22 | + (instancetype)sharedContactList;
23 | {
24 | static ContactList *sharedList;
25 | static dispatch_once_t onceToken;
26 | dispatch_once(&onceToken, ^{
27 | sharedList = [[ContactList alloc] init];
28 | });
29 | return sharedList;
30 | }
31 |
32 | - (id)init;
33 | {
34 | self = [super init];
35 | if (self != nil) {
36 | [self insertRandomContacts];
37 | }
38 | return self;
39 | }
40 |
41 | - (void)insertRandomContacts;
42 | {
43 | for (int i = 0; i < 42; ++i) {
44 | [self.contacts addObject:[Contact contactWithRancomName]];
45 | }
46 | }
47 |
48 | // We'll implement this through KVC
49 | - (NSMutableOrderedSet *)contacts;
50 | {
51 | return [self mutableOrderedSetValueForKey:@"backingContacts"];
52 | }
53 |
54 | //
55 | // Note: This code is in no way a recommended implementation. It's merely meant as an
56 | // example of what's possible, and how a custom implementation backing a KVC based
57 | // collection proxy object would look like.
58 | //
59 |
60 | - (NSUInteger)countOfBackingContacts;
61 | {
62 | return _contacts.size();
63 | }
64 |
65 | - (NSUInteger)indexInBackingContactsOfObject:(id)object;
66 | {
67 | auto i = std::find(_contacts.cbegin(), _contacts.cend(), object);
68 | return (i == _contacts.cend()) ? NSNotFound : (i - _contacts.cbegin());
69 | }
70 |
71 | - (NSArray *)backingContactsAtIndexes:(NSIndexSet *)indexes;
72 | {
73 | std::vector objects([indexes count], nil);
74 | __block auto it = objects.begin();
75 | [indexes enumerateIndexesUsingBlock:^(NSUInteger idx, BOOL *stop) {
76 | *(it++) = _contacts[idx];
77 | }];
78 | return [NSArray arrayWithObjects:objects.data() count:objects.size()];
79 | }
80 |
81 | - (void)getBackingContacts:(id __unsafe_unretained [])buffer range:(NSRange)range;
82 | {
83 | std::vector objects(range.length, nil);
84 | auto it1 = objects.begin();
85 | std::for_each(_contacts.cbegin() + range.location, _contacts.cbegin() + range.location + range.length, [&](Contact * const c){
86 | *(it1++) = c;
87 | });
88 | }
89 |
90 | - (void)insertBackingContacts:(NSArray *)array atIndexes:(NSIndexSet *)indexes;
91 | {
92 | __block NSUInteger idx1 = 0;
93 | [indexes enumerateIndexesUsingBlock:^(NSUInteger idx2, BOOL *stop) {
94 | id object = array[idx1++];
95 | _contacts.insert(_contacts.begin() + idx2, object);
96 | }];
97 | }
98 |
99 | - (void)removeBackingContactsAtIndexes:(NSIndexSet *)indexes;
100 | {
101 | [indexes enumerateRangesWithOptions:NSEnumerationReverse usingBlock:^(NSRange range, BOOL *stop) {
102 | _contacts.erase(_contacts.begin() + range.location, _contacts.begin() + range.location + range.length);
103 | }];
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/Contact Editor/CollectionViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // CollectionViewController.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import "CollectionViewController.h"
10 |
11 | #import "Contact.h"
12 | #import "DetailViewController.h"
13 | #import "ContactList.h"
14 |
15 |
16 |
17 | @interface CollectionViewController ()
18 |
19 |
20 | @property (nonatomic, strong) ContactList *contactList;
21 |
22 | @end
23 |
24 |
25 |
26 | @implementation CollectionViewController
27 |
28 | - (id)initWithStyle:(UITableViewStyle)style
29 | {
30 | self = [super initWithStyle:style];
31 | if (self) {
32 | // Custom initialization
33 | }
34 | return self;
35 | }
36 |
37 | - (void)viewDidLoad
38 | {
39 | [super viewDidLoad];
40 |
41 | self.contactList = [ContactList sharedContactList];
42 | self.navigationItem.rightBarButtonItem = self.editButtonItem;
43 | }
44 |
45 | - (void)viewWillAppear:(BOOL)animated;
46 | {
47 | [super viewWillAppear:animated];
48 | // We need to reload the visible cells here, because the detail view may have changed their contacts' names.
49 | [self updateVisibleCells];
50 | }
51 |
52 | - (void)updateVisibleCells;
53 | {
54 | for (UITableViewCell *cell in self.tableView.visibleCells) {
55 | NSIndexPath *indexPath = [self.tableView indexPathForCell:cell];
56 | Contact *contact = self.contactList.contacts[indexPath.row];
57 | cell.textLabel.text = contact.name;
58 | }
59 | }
60 |
61 | @end
62 |
63 |
64 |
65 | @implementation CollectionViewController (TableViewDataSourceAndDelegate)
66 |
67 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
68 | {
69 | return [self.self.contactList.contacts count];
70 | }
71 |
72 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
73 | {
74 | UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"contact" forIndexPath:indexPath];
75 | Contact *contact = self.self.contactList.contacts[indexPath.row];
76 | cell.textLabel.text = contact.name;
77 | return cell;
78 | }
79 |
80 | - (UITableViewCellEditingStyle)tableView:(UITableView *)tableView editingStyleForRowAtIndexPath:(NSIndexPath *)indexPath;
81 | {
82 | return UITableViewCellEditingStyleDelete;
83 | }
84 |
85 | - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath;
86 | {
87 | if (editingStyle == UITableViewCellEditingStyleDelete) {
88 | [self.contactList.contacts removeObjectAtIndex:indexPath.row];
89 | [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
90 | } else if (editingStyle == UITableViewCellEditingStyleInsert) {
91 | // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
92 | [self.contactList.contacts insertObject:[Contact contactWithRancomName] atIndex:indexPath.row];
93 | [tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
94 | }
95 | }
96 |
97 | - (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
98 | {
99 | [self.contactList.contacts moveObjectsAtIndexes:[NSIndexSet indexSetWithIndex:fromIndexPath.row] toIndex:toIndexPath.row];
100 | }
101 |
102 | - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
103 | {
104 | if ([segue.identifier isEqualToString:@"showDetails"]) {
105 | DetailViewController *vc = segue.destinationViewController;
106 | vc.contact = self.self.contactList.contacts[[self.tableView indexPathForSelectedRow].row];
107 | } else {
108 | NSAssert(NO, @"Unknown segue");
109 | }
110 | }
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/Contact Editor/Contact.m:
--------------------------------------------------------------------------------
1 | //
2 | // Contact.m
3 | // Contact Editor
4 | //
5 | // Created by Daniel Eggert on 01/12/2013.
6 | // Copyright (c) 2013 objc.io. All rights reserved.
7 | //
8 |
9 | #import "Contact.h"
10 |
11 |
12 |
13 | @implementation Contact
14 |
15 | + (instancetype)contactWithRancomName;
16 | {
17 | static NSArray *allFirstNames;
18 | static NSArray *allLastNames;
19 | static dispatch_once_t onceToken;
20 | dispatch_once(&onceToken, ^{
21 | //
22 | allFirstNames = @[@"Mary", @"Patricia", @"Linda", @"Barbara", @"Elizabeth", @"Jennifer", @"Maria", @"Susan", @"Margaret", @"Dorothy", @"Lisa", @"Nancy", @"Karen", @"Betty", @"Helen", @"Sandra", @"Donna", @"Carol", @"Ruth", @"Sharon", @"Michelle", @"Laura", @"Sarah", @"Kimberly", @"Deborah", @"Jessica", @"Shirley", @"Cynthia", @"Angela", @"Melissa", @"Brenda", @"Amy", @"Anna", @"Rebecca", @"Virginia", @"Kathleen", @"Pamela", @"Martha", @"Debra", @"Amanda", @"Stephanie", @"Carolyn", @"Christine", @"Marie", @"Janet", @"Catherine", @"Frances", @"Ann", @"Joyce", @"Diane", @"Alice", @"Julie", @"Heather", @"Teresa", @"Doris", @"Gloria", @"Evelyn", @"Jean", @"Cheryl", @"Mildred", @"Katherine", @"Joan", @"Ashley", @"Judith", @"Rose", @"Janice", @"Kelly", @"Nicole", @"Judy", @"Christina", @"Kathy", @"Theresa", @"Beverly", @"Denise", @"Tammy", @"Irene", @"Jane", @"Lori", @"Rachel", @"Marilyn", @"Andrea", @"Kathryn", @"Louise", @"Sara", @"Anne", @"Jacqueline", @"Wanda", @"Bonnie", @"Julia", @"Ruby", @"Lois", @"Tina", @"Phyllis", @"Norma", @"Paula", @"Diana", @"Annie", @"Lillian", @"Emily", @"Robin", @"Peggy", @"Crystal", @"Gladys", @"Rita", @"Dawn", @"Connie", @"Florence", @"Tracy", @"Edna", @"Tiffany", @"Carmen", @"Rosa", @"Cindy", @"Grace", @"Wendy", @"Victoria", @"Edith", @"Kim", @"Sherry", @"Sylvia", @"Josephine", @"Thelma", @"Shannon", @"Sheila", @"Ethel", @"Ellen", @"Elaine", @"Marjorie", @"Carrie", @"Charlotte", @"Monica", @"Esther", @"Pauline", @"Emma", @"Juanita", @"Anita", @"Rhonda", @"Hazel", @"Amber", @"Eva", @"Debbie", @"April", @"Leslie", @"Clara", @"Lucille", @"Jamie", @"Joanne", @"Eleanor", @"Valerie", @"Danielle", @"Megan", @"Alicia", @"Suzanne", @"Michele", @"Gail", @"Bertha", @"Darlene", @"Veronica", @"Jill", @"Erin", @"Geraldine", @"Lauren", @"Cathy", @"Joann", @"Lorraine", @"Lynn", @"Sally", @"Regina", @"Erica", @"Beatrice", @"Dolores", @"Bernice", @"Audrey", @"Yvonne", @"Annette", @"June", @"Samantha", @"Marion", @"Dana", @"Stacy", @"Ana", @"Renee", @"Ida", @"Vivian", @"Roberta", @"Holly", @"Brittany", @"Melanie", @"Loretta", @"Yolanda", @"Jeanette", @"Laurie", @"Katie", @"Kristen", @"Vanessa", @"Alma", @"Sue", @"Elsie", @"Beth", @"Jeanne", @"Vicki", @"Carla", @"Tara", @"Rosemary", @"Eileen", @"Terri", @"Gertrude", @"Lucy", @"Tonya", @"Ella", @"Stacey", @"Wilma", @"Gina", @"Kristin", @"Jessie", @"Natalie", @"Agnes", @"Vera", @"Willie", @"Charlene", @"Bessie", @"Delores", @"Melinda", @"Pearl", @"Arlene", @"Maureen", @"Colleen", @"Allison", @"Tamara", @"Joy", @"Georgia", @"Constance", @"Lillie", @"Claudia", @"Jackie", @"Marcia", @"Tanya", @"Nellie", @"Minnie", @"Marlene", @"Heidi", @"Glenda", @"Lydia", @"Viola", @"Courtney", @"Marian", @"Stella", @"Caroline", @"Dora", @"Jo", @"Vickie", @"Mattie", @"Terry", @"Maxine", @"Irma", @"Mabel", @"Marsha", @"Myrtle", @"Lena", @"Christy", @"Deanna", @"Patsy", @"Hilda", @"Gwendolyn", @"Jennie", @"Nora", @"Margie", @"Nina", @"Cassandra", @"Leah", @"Penny", @"Kay", @"Priscilla", @"Naomi", @"Carole", @"Brandy", @"Olga", @"Billie", @"Dianne", @"Tracey", @"Leona", @"Jenny", @"Felicia", @"Sonia", @"Miriam", @"Velma", @"Becky", @"Bobbie", @"Violet", @"Kristina", @"Toni", @"Misty", @"Mae", @"Shelly", @"Daisy", @"Ramona", @"Sherri", @"Erika", @"Katrina", @"Claire", @"Lindsey", @"Lindsay", @"Geneva", @"Guadalupe", @"Belinda", @"Margarita", @"Sheryl", @"Cora", @"Faye", @"Ada", @"Natasha", @"Sabrina", @"Isabel", @"Marguerite", @"Hattie", @"Harriet", @"Molly", @"Cecilia", @"Kristi", @"Brandi", @"Blanche", @"Sandy", @"Rosie", @"Joanna", @"Iris", @"Eunice", @"Angie", @"Inez", @"Lynda", @"Madeline", @"Amelia", @"Alberta", @"Genevieve", @"Monique"];
23 | //
24 | allLastNames = @[@"Smith", @"Johnson", @"Williams", @"Jones", @"Brown", @"Davis", @"Miller", @"Wilson", @"Moore", @"Taylor", @"Anderson", @"Thomas", @"Jackson", @"White", @"Harris", @"Martin", @"Thompson", @"Garcia", @"Martinez", @"Robinson", @"Clark", @"Rodriguez", @"Lewis", @"Lee", @"Walker", @"Hall", @"Allen", @"Young", @"Hernandez", @"King", @"Wright", @"Lopez", @"Hill", @"Scott", @"Green", @"Adams", @"Baker", @"Gonzalez", @"Nelson", @"Carter", @"Mitchell", @"Perez", @"Roberts", @"Turner", @"Phillips", @"Campbell", @"Parker", @"Evans", @"Edwards", @"Collins", @"Stewart", @"Sanchez", @"Morris", @"Rogers", @"Reed", @"Cook", @"Morgan", @"Bell", @"Murphy", @"Bailey", @"Rivera", @"Cooper", @"Richardson", @"Cox", @"Howard", @"Ward", @"Torres", @"Peterson", @"Gray", @"Ramirez", @"James", @"Watson", @"Brooks", @"Kelly", @"Sanders", @"Price", @"Bennett", @"Wood", @"Barnes", @"Ross", @"Henderson", @"Coleman", @"Jenkins", @"Perry", @"Powell", @"Long", @"Patterson", @"Hughes", @"Flores", @"Washington", @"Butler", @"Simmons", @"Foster", @"Gonzales", @"Bryant", @"Alexander", @"Russell", @"Griffin", @"Diaz", @"Hayes", @"Myers", @"Ford", @"Hamilton", @"Graham", @"Sullivan", @"Wallace", @"Woods", @"Cole", @"West", @"Jordan", @"Owens", @"Reynolds", @"Fisher", @"Ellis", @"Harrison", @"Gibson", @"Mcdonald", @"Cruz", @"Marshall", @"Ortiz", @"Gomez", @"Murray", @"Freeman", @"Wells", @"Webb", @"Simpson", @"Stevens", @"Tucker", @"Porter", @"Hunter", @"Hicks", @"Crawford", @"Henry", @"Boyd", @"Mason", @"Morales", @"Kennedy", @"Warren", @"Dixon", @"Ramos", @"Reyes", @"Burns", @"Gordon", @"Shaw", @"Holmes", @"Rice", @"Robertson", @"Hunt", @"Black", @"Daniels", @"Palmer", @"Mills", @"Nichols", @"Grant", @"Knight", @"Ferguson", @"Rose", @"Stone", @"Hawkins", @"Dunn", @"Perkins", @"Hudson", @"Spencer", @"Gardner", @"Stephens", @"Payne", @"Pierce", @"Berry", @"Matthews", @"Arnold", @"Wagner", @"Willis", @"Ray", @"Watkins", @"Olson", @"Carroll", @"Duncan", @"Snyder", @"Hart", @"Cunningham", @"Bradley", @"Lane", @"Andrews", @"Ruiz", @"Harper", @"Fox", @"Riley", @"Armstrong", @"Carpenter", @"Weaver", @"Greene", @"Lawrence", @"Elliott", @"Chavez", @"Sims", @"Austin", @"Peters", @"Kelley", @"Franklin", @"Lawson", @"Fields", @"Gutierrez", @"Ryan", @"Schmidt", @"Carr", @"Vasquez", @"Castillo", @"Wheeler", @"Chapman", @"Oliver", @"Montgomery", @"Richards", @"Williamson", @"Johnston", @"Banks", @"Meyer", @"Bishop", @"Mccoy", @"Howell", @"Alvarez", @"Morrison", @"Hansen", @"Fernandez", @"Garza", @"Harvey", @"Little", @"Burton", @"Stanley", @"Nguyen", @"George", @"Jacobs", @"Reid", @"Kim", @"Fuller", @"Lynch", @"Dean", @"Gilbert", @"Garrett", @"Romero", @"Welch", @"Larson", @"Frazier", @"Burke", @"Hanson", @"Day", @"Mendoza", @"Moreno", @"Bowman", @"Medina", @"Fowler", @"Brewer", @"Hoffman", @"Carlson", @"Silva", @"Pearson", @"Holland", @"Douglas", @"Fleming", @"Jensen", @"Vargas", @"Byrd", @"Davidson", @"Hopkins", @"May", @"Terry", @"Herrera", @"Wade", @"Soto", @"Walters", @"Curtis", @"Neal", @"Caldwell", @"Lowe", @"Jennings", @"Barnett", @"Graves", @"Jimenez", @"Horton", @"Shelton", @"Barrett", @"Obrien", @"Castro", @"Sutton", @"Gregory", @"Mckinney", @"Lucas", @"Miles", @"Craig", @"Rodriquez", @"Chambers", @"Holt", @"Lambert", @"Fletcher", @"Watts", @"Bates", @"Hale", @"Rhodes", @"Pena", @"Beck", @"Newman", @"Haynes", @"Mcdaniel", @"Mendez", @"Bush", @"Vaughn", @"Parks", @"Dawson", @"Santiago", @"Norris", @"Hardy", @"Love", @"Steele", @"Curry", @"Powers", @"Schultz", @"Barker", @"Guzman", @"Page", @"Munoz", @"Ball", @"Keller", @"Chandler", @"Weber", @"Leonard", @"Walsh"];
25 | });
26 | Contact *result = [[self alloc] init];
27 | result.name = [NSString stringWithFormat:@"%@ %@",
28 | allFirstNames[arc4random_uniform([allFirstNames count])],
29 | allLastNames[arc4random_uniform([allLastNames count])]];
30 | return result;
31 | }
32 |
33 | - (BOOL)validateName:(NSString **)nameP error:(NSError * __autoreleasing *)error
34 | {
35 | if (*nameP == nil) {
36 | *nameP = @"";
37 | return YES;
38 | } else {
39 | NSArray *components = [*nameP componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
40 | components = [components filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString *component, NSDictionary *bindings) {
41 | return (0 < [component length]);
42 | }]];
43 | *nameP = [components componentsJoinedByString:@" "];
44 | return YES;
45 | }
46 | }
47 |
48 | - (BOOL)validateEmail:(NSString **)emailP error:(NSError * __autoreleasing *)error
49 | {
50 | if (*emailP == nil) {
51 | *emailP = @"";
52 | return YES;
53 | } else {
54 | NSArray *components = [*emailP componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
55 | *emailP = [[components componentsJoinedByString:@""] lowercaseString];
56 | return YES;
57 | }
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/Contact Editor/Base.lproj/Main_iPhone.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/Contact Editor.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3E60E743184B639B0016C11B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E60E742184B639B0016C11B /* Foundation.framework */; };
11 | 3E60E745184B639B0016C11B /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E60E744184B639B0016C11B /* CoreGraphics.framework */; };
12 | 3E60E747184B639B0016C11B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E60E746184B639B0016C11B /* UIKit.framework */; };
13 | 3E60E74D184B639B0016C11B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3E60E74B184B639B0016C11B /* InfoPlist.strings */; };
14 | 3E60E74F184B639B0016C11B /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E60E74E184B639B0016C11B /* main.m */; };
15 | 3E60E753184B639B0016C11B /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E60E752184B639B0016C11B /* AppDelegate.m */; };
16 | 3E60E756184B639B0016C11B /* Main_iPhone.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3E60E754184B639B0016C11B /* Main_iPhone.storyboard */; };
17 | 3E60E759184B639B0016C11B /* Main_iPad.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3E60E757184B639B0016C11B /* Main_iPad.storyboard */; };
18 | 3E60E75C184B639B0016C11B /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E60E75B184B639B0016C11B /* DetailViewController.m */; };
19 | 3E60E75E184B639B0016C11B /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 3E60E75D184B639B0016C11B /* Images.xcassets */; };
20 | 3E60E765184B639B0016C11B /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E60E764184B639B0016C11B /* XCTest.framework */; };
21 | 3E60E766184B639B0016C11B /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E60E742184B639B0016C11B /* Foundation.framework */; };
22 | 3E60E767184B639B0016C11B /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3E60E746184B639B0016C11B /* UIKit.framework */; };
23 | 3E60E76F184B639B0016C11B /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3E60E76D184B639B0016C11B /* InfoPlist.strings */; };
24 | 3E60E771184B639B0016C11B /* Contact_EditorTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E60E770184B639B0016C11B /* Contact_EditorTests.m */; };
25 | 3E60E77C184B63B70016C11B /* Contact.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E60E77B184B63B70016C11B /* Contact.m */; };
26 | 3E60E77F184B66520016C11B /* CollectionViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3E60E77E184B66520016C11B /* CollectionViewController.m */; };
27 | 3EE0600B184D184C00982623 /* ContactList.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3EE0600A184D184C00982623 /* ContactList.mm */; };
28 | /* End PBXBuildFile section */
29 |
30 | /* Begin PBXContainerItemProxy section */
31 | 3E60E768184B639B0016C11B /* PBXContainerItemProxy */ = {
32 | isa = PBXContainerItemProxy;
33 | containerPortal = 3E60E737184B639B0016C11B /* Project object */;
34 | proxyType = 1;
35 | remoteGlobalIDString = 3E60E73E184B639B0016C11B;
36 | remoteInfo = "Contact Editor";
37 | };
38 | /* End PBXContainerItemProxy section */
39 |
40 | /* Begin PBXFileReference section */
41 | 3E60E73F184B639B0016C11B /* Contact Editor.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "Contact Editor.app"; sourceTree = BUILT_PRODUCTS_DIR; };
42 | 3E60E742184B639B0016C11B /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
43 | 3E60E744184B639B0016C11B /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
44 | 3E60E746184B639B0016C11B /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
45 | 3E60E74A184B639B0016C11B /* Contact Editor-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Contact Editor-Info.plist"; sourceTree = ""; };
46 | 3E60E74C184B639B0016C11B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
47 | 3E60E74E184B639B0016C11B /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; };
48 | 3E60E750184B639B0016C11B /* Contact Editor-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Contact Editor-Prefix.pch"; sourceTree = ""; };
49 | 3E60E751184B639B0016C11B /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; };
50 | 3E60E752184B639B0016C11B /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
51 | 3E60E755184B639B0016C11B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPhone.storyboard; sourceTree = ""; };
52 | 3E60E758184B639B0016C11B /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main_iPad.storyboard; sourceTree = ""; };
53 | 3E60E75A184B639B0016C11B /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = ""; };
54 | 3E60E75B184B639B0016C11B /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = ""; };
55 | 3E60E75D184B639B0016C11B /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
56 | 3E60E763184B639B0016C11B /* Contact EditorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Contact EditorTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
57 | 3E60E764184B639B0016C11B /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
58 | 3E60E76C184B639B0016C11B /* Contact EditorTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Contact EditorTests-Info.plist"; sourceTree = ""; };
59 | 3E60E76E184B639B0016C11B /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; };
60 | 3E60E770184B639B0016C11B /* Contact_EditorTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Contact_EditorTests.m; sourceTree = ""; };
61 | 3E60E77A184B63B70016C11B /* Contact.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Contact.h; sourceTree = ""; };
62 | 3E60E77B184B63B70016C11B /* Contact.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Contact.m; sourceTree = ""; };
63 | 3E60E77D184B66520016C11B /* CollectionViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CollectionViewController.h; sourceTree = ""; };
64 | 3E60E77E184B66520016C11B /* CollectionViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CollectionViewController.m; sourceTree = ""; };
65 | 3EE06009184D184C00982623 /* ContactList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ContactList.h; sourceTree = ""; };
66 | 3EE0600A184D184C00982623 /* ContactList.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ContactList.mm; sourceTree = ""; };
67 | /* End PBXFileReference section */
68 |
69 | /* Begin PBXFrameworksBuildPhase section */
70 | 3E60E73C184B639B0016C11B /* Frameworks */ = {
71 | isa = PBXFrameworksBuildPhase;
72 | buildActionMask = 2147483647;
73 | files = (
74 | 3E60E745184B639B0016C11B /* CoreGraphics.framework in Frameworks */,
75 | 3E60E747184B639B0016C11B /* UIKit.framework in Frameworks */,
76 | 3E60E743184B639B0016C11B /* Foundation.framework in Frameworks */,
77 | );
78 | runOnlyForDeploymentPostprocessing = 0;
79 | };
80 | 3E60E760184B639B0016C11B /* Frameworks */ = {
81 | isa = PBXFrameworksBuildPhase;
82 | buildActionMask = 2147483647;
83 | files = (
84 | 3E60E765184B639B0016C11B /* XCTest.framework in Frameworks */,
85 | 3E60E767184B639B0016C11B /* UIKit.framework in Frameworks */,
86 | 3E60E766184B639B0016C11B /* Foundation.framework in Frameworks */,
87 | );
88 | runOnlyForDeploymentPostprocessing = 0;
89 | };
90 | /* End PBXFrameworksBuildPhase section */
91 |
92 | /* Begin PBXGroup section */
93 | 3E60E736184B639B0016C11B = {
94 | isa = PBXGroup;
95 | children = (
96 | 3E60E748184B639B0016C11B /* Contact Editor */,
97 | 3E60E76A184B639B0016C11B /* Contact EditorTests */,
98 | 3E60E741184B639B0016C11B /* Frameworks */,
99 | 3E60E740184B639B0016C11B /* Products */,
100 | );
101 | sourceTree = "";
102 | };
103 | 3E60E740184B639B0016C11B /* Products */ = {
104 | isa = PBXGroup;
105 | children = (
106 | 3E60E73F184B639B0016C11B /* Contact Editor.app */,
107 | 3E60E763184B639B0016C11B /* Contact EditorTests.xctest */,
108 | );
109 | name = Products;
110 | sourceTree = "";
111 | };
112 | 3E60E741184B639B0016C11B /* Frameworks */ = {
113 | isa = PBXGroup;
114 | children = (
115 | 3E60E742184B639B0016C11B /* Foundation.framework */,
116 | 3E60E744184B639B0016C11B /* CoreGraphics.framework */,
117 | 3E60E746184B639B0016C11B /* UIKit.framework */,
118 | 3E60E764184B639B0016C11B /* XCTest.framework */,
119 | );
120 | name = Frameworks;
121 | sourceTree = "";
122 | };
123 | 3E60E748184B639B0016C11B /* Contact Editor */ = {
124 | isa = PBXGroup;
125 | children = (
126 | 3E60E751184B639B0016C11B /* AppDelegate.h */,
127 | 3E60E752184B639B0016C11B /* AppDelegate.m */,
128 | 3E60E754184B639B0016C11B /* Main_iPhone.storyboard */,
129 | 3E60E757184B639B0016C11B /* Main_iPad.storyboard */,
130 | 3E60E77D184B66520016C11B /* CollectionViewController.h */,
131 | 3E60E77E184B66520016C11B /* CollectionViewController.m */,
132 | 3E60E75A184B639B0016C11B /* DetailViewController.h */,
133 | 3E60E75B184B639B0016C11B /* DetailViewController.m */,
134 | 3E60E77A184B63B70016C11B /* Contact.h */,
135 | 3E60E77B184B63B70016C11B /* Contact.m */,
136 | 3EE06009184D184C00982623 /* ContactList.h */,
137 | 3EE0600A184D184C00982623 /* ContactList.mm */,
138 | 3E60E75D184B639B0016C11B /* Images.xcassets */,
139 | 3E60E749184B639B0016C11B /* Supporting Files */,
140 | );
141 | path = "Contact Editor";
142 | sourceTree = "";
143 | };
144 | 3E60E749184B639B0016C11B /* Supporting Files */ = {
145 | isa = PBXGroup;
146 | children = (
147 | 3E60E74A184B639B0016C11B /* Contact Editor-Info.plist */,
148 | 3E60E74B184B639B0016C11B /* InfoPlist.strings */,
149 | 3E60E74E184B639B0016C11B /* main.m */,
150 | 3E60E750184B639B0016C11B /* Contact Editor-Prefix.pch */,
151 | );
152 | name = "Supporting Files";
153 | sourceTree = "";
154 | };
155 | 3E60E76A184B639B0016C11B /* Contact EditorTests */ = {
156 | isa = PBXGroup;
157 | children = (
158 | 3E60E770184B639B0016C11B /* Contact_EditorTests.m */,
159 | 3E60E76B184B639B0016C11B /* Supporting Files */,
160 | );
161 | path = "Contact EditorTests";
162 | sourceTree = "";
163 | };
164 | 3E60E76B184B639B0016C11B /* Supporting Files */ = {
165 | isa = PBXGroup;
166 | children = (
167 | 3E60E76C184B639B0016C11B /* Contact EditorTests-Info.plist */,
168 | 3E60E76D184B639B0016C11B /* InfoPlist.strings */,
169 | );
170 | name = "Supporting Files";
171 | sourceTree = "";
172 | };
173 | /* End PBXGroup section */
174 |
175 | /* Begin PBXNativeTarget section */
176 | 3E60E73E184B639B0016C11B /* Contact Editor */ = {
177 | isa = PBXNativeTarget;
178 | buildConfigurationList = 3E60E774184B639B0016C11B /* Build configuration list for PBXNativeTarget "Contact Editor" */;
179 | buildPhases = (
180 | 3E60E73B184B639B0016C11B /* Sources */,
181 | 3E60E73C184B639B0016C11B /* Frameworks */,
182 | 3E60E73D184B639B0016C11B /* Resources */,
183 | );
184 | buildRules = (
185 | );
186 | dependencies = (
187 | );
188 | name = "Contact Editor";
189 | productName = "Contact Editor";
190 | productReference = 3E60E73F184B639B0016C11B /* Contact Editor.app */;
191 | productType = "com.apple.product-type.application";
192 | };
193 | 3E60E762184B639B0016C11B /* Contact EditorTests */ = {
194 | isa = PBXNativeTarget;
195 | buildConfigurationList = 3E60E777184B639B0016C11B /* Build configuration list for PBXNativeTarget "Contact EditorTests" */;
196 | buildPhases = (
197 | 3E60E75F184B639B0016C11B /* Sources */,
198 | 3E60E760184B639B0016C11B /* Frameworks */,
199 | 3E60E761184B639B0016C11B /* Resources */,
200 | );
201 | buildRules = (
202 | );
203 | dependencies = (
204 | 3E60E769184B639B0016C11B /* PBXTargetDependency */,
205 | );
206 | name = "Contact EditorTests";
207 | productName = "Contact EditorTests";
208 | productReference = 3E60E763184B639B0016C11B /* Contact EditorTests.xctest */;
209 | productType = "com.apple.product-type.bundle.unit-test";
210 | };
211 | /* End PBXNativeTarget section */
212 |
213 | /* Begin PBXProject section */
214 | 3E60E737184B639B0016C11B /* Project object */ = {
215 | isa = PBXProject;
216 | attributes = {
217 | LastUpgradeCheck = 0500;
218 | ORGANIZATIONNAME = objc.io;
219 | TargetAttributes = {
220 | 3E60E762184B639B0016C11B = {
221 | TestTargetID = 3E60E73E184B639B0016C11B;
222 | };
223 | };
224 | };
225 | buildConfigurationList = 3E60E73A184B639B0016C11B /* Build configuration list for PBXProject "Contact Editor" */;
226 | compatibilityVersion = "Xcode 3.2";
227 | developmentRegion = English;
228 | hasScannedForEncodings = 0;
229 | knownRegions = (
230 | en,
231 | Base,
232 | );
233 | mainGroup = 3E60E736184B639B0016C11B;
234 | productRefGroup = 3E60E740184B639B0016C11B /* Products */;
235 | projectDirPath = "";
236 | projectRoot = "";
237 | targets = (
238 | 3E60E73E184B639B0016C11B /* Contact Editor */,
239 | 3E60E762184B639B0016C11B /* Contact EditorTests */,
240 | );
241 | };
242 | /* End PBXProject section */
243 |
244 | /* Begin PBXResourcesBuildPhase section */
245 | 3E60E73D184B639B0016C11B /* Resources */ = {
246 | isa = PBXResourcesBuildPhase;
247 | buildActionMask = 2147483647;
248 | files = (
249 | 3E60E759184B639B0016C11B /* Main_iPad.storyboard in Resources */,
250 | 3E60E75E184B639B0016C11B /* Images.xcassets in Resources */,
251 | 3E60E756184B639B0016C11B /* Main_iPhone.storyboard in Resources */,
252 | 3E60E74D184B639B0016C11B /* InfoPlist.strings in Resources */,
253 | );
254 | runOnlyForDeploymentPostprocessing = 0;
255 | };
256 | 3E60E761184B639B0016C11B /* Resources */ = {
257 | isa = PBXResourcesBuildPhase;
258 | buildActionMask = 2147483647;
259 | files = (
260 | 3E60E76F184B639B0016C11B /* InfoPlist.strings in Resources */,
261 | );
262 | runOnlyForDeploymentPostprocessing = 0;
263 | };
264 | /* End PBXResourcesBuildPhase section */
265 |
266 | /* Begin PBXSourcesBuildPhase section */
267 | 3E60E73B184B639B0016C11B /* Sources */ = {
268 | isa = PBXSourcesBuildPhase;
269 | buildActionMask = 2147483647;
270 | files = (
271 | 3EE0600B184D184C00982623 /* ContactList.mm in Sources */,
272 | 3E60E77C184B63B70016C11B /* Contact.m in Sources */,
273 | 3E60E75C184B639B0016C11B /* DetailViewController.m in Sources */,
274 | 3E60E753184B639B0016C11B /* AppDelegate.m in Sources */,
275 | 3E60E77F184B66520016C11B /* CollectionViewController.m in Sources */,
276 | 3E60E74F184B639B0016C11B /* main.m in Sources */,
277 | );
278 | runOnlyForDeploymentPostprocessing = 0;
279 | };
280 | 3E60E75F184B639B0016C11B /* Sources */ = {
281 | isa = PBXSourcesBuildPhase;
282 | buildActionMask = 2147483647;
283 | files = (
284 | 3E60E771184B639B0016C11B /* Contact_EditorTests.m in Sources */,
285 | );
286 | runOnlyForDeploymentPostprocessing = 0;
287 | };
288 | /* End PBXSourcesBuildPhase section */
289 |
290 | /* Begin PBXTargetDependency section */
291 | 3E60E769184B639B0016C11B /* PBXTargetDependency */ = {
292 | isa = PBXTargetDependency;
293 | target = 3E60E73E184B639B0016C11B /* Contact Editor */;
294 | targetProxy = 3E60E768184B639B0016C11B /* PBXContainerItemProxy */;
295 | };
296 | /* End PBXTargetDependency section */
297 |
298 | /* Begin PBXVariantGroup section */
299 | 3E60E74B184B639B0016C11B /* InfoPlist.strings */ = {
300 | isa = PBXVariantGroup;
301 | children = (
302 | 3E60E74C184B639B0016C11B /* en */,
303 | );
304 | name = InfoPlist.strings;
305 | sourceTree = "";
306 | };
307 | 3E60E754184B639B0016C11B /* Main_iPhone.storyboard */ = {
308 | isa = PBXVariantGroup;
309 | children = (
310 | 3E60E755184B639B0016C11B /* Base */,
311 | );
312 | name = Main_iPhone.storyboard;
313 | sourceTree = "";
314 | };
315 | 3E60E757184B639B0016C11B /* Main_iPad.storyboard */ = {
316 | isa = PBXVariantGroup;
317 | children = (
318 | 3E60E758184B639B0016C11B /* Base */,
319 | );
320 | name = Main_iPad.storyboard;
321 | sourceTree = "";
322 | };
323 | 3E60E76D184B639B0016C11B /* InfoPlist.strings */ = {
324 | isa = PBXVariantGroup;
325 | children = (
326 | 3E60E76E184B639B0016C11B /* en */,
327 | );
328 | name = InfoPlist.strings;
329 | sourceTree = "";
330 | };
331 | /* End PBXVariantGroup section */
332 |
333 | /* Begin XCBuildConfiguration section */
334 | 3E60E772184B639B0016C11B /* Debug */ = {
335 | isa = XCBuildConfiguration;
336 | buildSettings = {
337 | ALWAYS_SEARCH_USER_PATHS = NO;
338 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
339 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
340 | CLANG_CXX_LIBRARY = "libc++";
341 | CLANG_ENABLE_MODULES = YES;
342 | CLANG_ENABLE_OBJC_ARC = YES;
343 | CLANG_WARN_BOOL_CONVERSION = YES;
344 | CLANG_WARN_CONSTANT_CONVERSION = YES;
345 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
346 | CLANG_WARN_EMPTY_BODY = YES;
347 | CLANG_WARN_ENUM_CONVERSION = YES;
348 | CLANG_WARN_INT_CONVERSION = YES;
349 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
350 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
351 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
352 | COPY_PHASE_STRIP = NO;
353 | GCC_C_LANGUAGE_STANDARD = gnu99;
354 | GCC_DYNAMIC_NO_PIC = NO;
355 | GCC_OPTIMIZATION_LEVEL = 0;
356 | GCC_PREPROCESSOR_DEFINITIONS = (
357 | "DEBUG=1",
358 | "$(inherited)",
359 | );
360 | GCC_SYMBOLS_PRIVATE_EXTERN = NO;
361 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
362 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
363 | GCC_WARN_UNDECLARED_SELECTOR = YES;
364 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
365 | GCC_WARN_UNUSED_FUNCTION = YES;
366 | GCC_WARN_UNUSED_VARIABLE = YES;
367 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
368 | ONLY_ACTIVE_ARCH = YES;
369 | SDKROOT = iphoneos;
370 | TARGETED_DEVICE_FAMILY = "1,2";
371 | };
372 | name = Debug;
373 | };
374 | 3E60E773184B639B0016C11B /* Release */ = {
375 | isa = XCBuildConfiguration;
376 | buildSettings = {
377 | ALWAYS_SEARCH_USER_PATHS = NO;
378 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
379 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
380 | CLANG_CXX_LIBRARY = "libc++";
381 | CLANG_ENABLE_MODULES = YES;
382 | CLANG_ENABLE_OBJC_ARC = YES;
383 | CLANG_WARN_BOOL_CONVERSION = YES;
384 | CLANG_WARN_CONSTANT_CONVERSION = YES;
385 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
386 | CLANG_WARN_EMPTY_BODY = YES;
387 | CLANG_WARN_ENUM_CONVERSION = YES;
388 | CLANG_WARN_INT_CONVERSION = YES;
389 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
390 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
391 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
392 | COPY_PHASE_STRIP = YES;
393 | ENABLE_NS_ASSERTIONS = NO;
394 | GCC_C_LANGUAGE_STANDARD = gnu99;
395 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
396 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
397 | GCC_WARN_UNDECLARED_SELECTOR = YES;
398 | GCC_WARN_UNINITIALIZED_AUTOS = YES;
399 | GCC_WARN_UNUSED_FUNCTION = YES;
400 | GCC_WARN_UNUSED_VARIABLE = YES;
401 | IPHONEOS_DEPLOYMENT_TARGET = 7.0;
402 | SDKROOT = iphoneos;
403 | TARGETED_DEVICE_FAMILY = "1,2";
404 | VALIDATE_PRODUCT = YES;
405 | };
406 | name = Release;
407 | };
408 | 3E60E775184B639B0016C11B /* Debug */ = {
409 | isa = XCBuildConfiguration;
410 | buildSettings = {
411 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
412 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
413 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
414 | GCC_PREFIX_HEADER = "Contact Editor/Contact Editor-Prefix.pch";
415 | INFOPLIST_FILE = "Contact Editor/Contact Editor-Info.plist";
416 | PRODUCT_NAME = "$(TARGET_NAME)";
417 | WRAPPER_EXTENSION = app;
418 | };
419 | name = Debug;
420 | };
421 | 3E60E776184B639B0016C11B /* Release */ = {
422 | isa = XCBuildConfiguration;
423 | buildSettings = {
424 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
425 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
426 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
427 | GCC_PREFIX_HEADER = "Contact Editor/Contact Editor-Prefix.pch";
428 | INFOPLIST_FILE = "Contact Editor/Contact Editor-Info.plist";
429 | PRODUCT_NAME = "$(TARGET_NAME)";
430 | WRAPPER_EXTENSION = app;
431 | };
432 | name = Release;
433 | };
434 | 3E60E778184B639B0016C11B /* Debug */ = {
435 | isa = XCBuildConfiguration;
436 | buildSettings = {
437 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
438 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Contact Editor.app/Contact Editor";
439 | FRAMEWORK_SEARCH_PATHS = (
440 | "$(SDKROOT)/Developer/Library/Frameworks",
441 | "$(inherited)",
442 | "$(DEVELOPER_FRAMEWORKS_DIR)",
443 | );
444 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
445 | GCC_PREFIX_HEADER = "Contact Editor/Contact Editor-Prefix.pch";
446 | GCC_PREPROCESSOR_DEFINITIONS = (
447 | "DEBUG=1",
448 | "$(inherited)",
449 | );
450 | INFOPLIST_FILE = "Contact EditorTests/Contact EditorTests-Info.plist";
451 | PRODUCT_NAME = "$(TARGET_NAME)";
452 | TEST_HOST = "$(BUNDLE_LOADER)";
453 | WRAPPER_EXTENSION = xctest;
454 | };
455 | name = Debug;
456 | };
457 | 3E60E779184B639B0016C11B /* Release */ = {
458 | isa = XCBuildConfiguration;
459 | buildSettings = {
460 | ARCHS = "$(ARCHS_STANDARD_INCLUDING_64_BIT)";
461 | BUNDLE_LOADER = "$(BUILT_PRODUCTS_DIR)/Contact Editor.app/Contact Editor";
462 | FRAMEWORK_SEARCH_PATHS = (
463 | "$(SDKROOT)/Developer/Library/Frameworks",
464 | "$(inherited)",
465 | "$(DEVELOPER_FRAMEWORKS_DIR)",
466 | );
467 | GCC_PRECOMPILE_PREFIX_HEADER = YES;
468 | GCC_PREFIX_HEADER = "Contact Editor/Contact Editor-Prefix.pch";
469 | INFOPLIST_FILE = "Contact EditorTests/Contact EditorTests-Info.plist";
470 | PRODUCT_NAME = "$(TARGET_NAME)";
471 | TEST_HOST = "$(BUNDLE_LOADER)";
472 | WRAPPER_EXTENSION = xctest;
473 | };
474 | name = Release;
475 | };
476 | /* End XCBuildConfiguration section */
477 |
478 | /* Begin XCConfigurationList section */
479 | 3E60E73A184B639B0016C11B /* Build configuration list for PBXProject "Contact Editor" */ = {
480 | isa = XCConfigurationList;
481 | buildConfigurations = (
482 | 3E60E772184B639B0016C11B /* Debug */,
483 | 3E60E773184B639B0016C11B /* Release */,
484 | );
485 | defaultConfigurationIsVisible = 0;
486 | defaultConfigurationName = Release;
487 | };
488 | 3E60E774184B639B0016C11B /* Build configuration list for PBXNativeTarget "Contact Editor" */ = {
489 | isa = XCConfigurationList;
490 | buildConfigurations = (
491 | 3E60E775184B639B0016C11B /* Debug */,
492 | 3E60E776184B639B0016C11B /* Release */,
493 | );
494 | defaultConfigurationIsVisible = 0;
495 | defaultConfigurationName = Release;
496 | };
497 | 3E60E777184B639B0016C11B /* Build configuration list for PBXNativeTarget "Contact EditorTests" */ = {
498 | isa = XCConfigurationList;
499 | buildConfigurations = (
500 | 3E60E778184B639B0016C11B /* Debug */,
501 | 3E60E779184B639B0016C11B /* Release */,
502 | );
503 | defaultConfigurationIsVisible = 0;
504 | defaultConfigurationName = Release;
505 | };
506 | /* End XCConfigurationList section */
507 | };
508 | rootObject = 3E60E737184B639B0016C11B /* Project object */;
509 | }
510 |
--------------------------------------------------------------------------------