├── .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 | --------------------------------------------------------------------------------