├── .DS_Store ├── .gitignore ├── README.md ├── SharingViaKeychain ├── .DS_Store ├── SharedDataLayer │ ├── Info.plist │ ├── KeychainItemWrapper.h │ ├── KeychainItemWrapper.m │ └── SharedDataLayer.h ├── SharedDataLayerTests │ ├── Info.plist │ └── SharedDataLayerTests.m ├── SharingViaKeychain WatchKit App │ ├── Base.lproj │ │ └── Interface.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── Info.plist ├── SharingViaKeychain WatchKit Extension │ ├── Images.xcassets │ │ └── README__ignoredByTemplate__ │ ├── Info.plist │ ├── InterfaceController.swift │ ├── PushNotificationPayload.apns │ ├── SharingViaKeychain WatchKit Extension-Bridging-Header.h │ └── SharingViaKeychain WatchKit Extension.entitlements ├── SharingViaKeychain.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── SharingViaKeychain │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── SharingViaKeychain-Bridging-Header.h │ ├── SharingViaKeychain.entitlements │ └── ViewController.swift └── SharingViaKeychainTests │ ├── Info.plist │ └── SharingViaKeychainTests.swift ├── SharingWithFileCoordinator ├── .DS_Store ├── SharingWithFileCoordinator WatchKit App │ ├── Base.lproj │ │ └── Interface.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── Info.plist ├── SharingWithFileCoordinator WatchKit Extension │ ├── Images.xcassets │ │ └── README__ignoredByTemplate__ │ ├── Info.plist │ ├── InterfaceController.swift │ ├── SharingWithFileCoordinator WatchKit Extension.entitlements │ └── TodoTableRowController.swift ├── SharingWithFileCoordinator.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── SharingWithFileCoordinator │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── InputTableViewCell.swift │ ├── SharingWithFileCoordinator.entitlements │ └── TodoListTableViewController.swift └── SharingWithFileCoordinatorTests │ ├── Info.plist │ └── SharingWithFileCoordinatorTests.swift ├── SharingWithFramework ├── MySharedDataLayer │ ├── Info.plist │ └── MySharedData.swift ├── MySharedDataLayerTests │ ├── Info.plist │ └── MySharedDataLayerTests.swift ├── SharingWithFramework WatchKit App │ ├── Base.lproj │ │ └── Interface.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── Info.plist ├── SharingWithFramework WatchKit Extension │ ├── Images.xcassets │ │ └── README__ignoredByTemplate__ │ ├── Info.plist │ └── InterfaceController.swift ├── SharingWithFramework.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── SharingWithFramework │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ └── ViewController.swift └── SharingWithFrameworkTests │ ├── Info.plist │ └── SharingWithFrameworkTests.swift ├── SharingWithUserDefaults ├── SharingWithUserDefaults WatchKit App │ ├── Base.lproj │ │ └── Interface.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ └── Info.plist ├── SharingWithUserDefaults WatchKit Extension │ ├── Images.xcassets │ │ └── README__ignoredByTemplate__ │ ├── Info.plist │ ├── InterfaceController.swift │ └── SharingWithUserDefaults WatchKit Extension.entitlements ├── SharingWithUserDefaults.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata ├── SharingWithUserDefaults │ ├── AppDelegate.swift │ ├── Base.lproj │ │ ├── LaunchScreen.xib │ │ └── Main.storyboard │ ├── Images.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Info.plist │ ├── SharingWithUserDefaults.entitlements │ └── ViewController.swift └── SharingWithUserDefaultsTests │ ├── Info.plist │ └── SharingWithUserDefaultsTests.swift └── WatchKitArchitecture.pdf /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NatashaTheRobot/watchkit/3e05c122b289bfcfcd57cd2f1405cf19b61b1546/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | build/ 4 | *.pbxuser 5 | !default.pbxuser 6 | *.mode1v3 7 | !default.mode1v3 8 | *.mode2v3 9 | !default.mode2v3 10 | *.perspectivev3 11 | !default.perspectivev3 12 | xcuserdata 13 | *.xccheckout 14 | *.moved-aside 15 | DerivedData 16 | *.hmap 17 | *.ipa 18 | *.xcuserstate 19 | 20 | # CocoaPods 21 | # 22 | # We recommend against adding the Pods directory to your .gitignore. However 23 | # you should judge for yourself, the pros and cons are mentioned at: 24 | # http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control 25 | # 26 | # Pods/ 27 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # watchkit 2 | Sharing Data with WatchKit Examples 3 | -------------------------------------------------------------------------------- /SharingViaKeychain/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NatashaTheRobot/watchkit/3e05c122b289bfcfcd57cd2f1405cf19b61b1546/SharingViaKeychain/.DS_Store -------------------------------------------------------------------------------- /SharingViaKeychain/SharedDataLayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharedDataLayer/KeychainItemWrapper.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: KeychainItemWrapper.h 3 | Abstract: 4 | Objective-C wrapper for accessing a single keychain item. 5 | 6 | Version: 1.2 - ARCified 7 | 8 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 9 | Inc. ("Apple") in consideration of your agreement to the following 10 | terms, and your use, installation, modification or redistribution of 11 | this Apple software constitutes acceptance of these terms. If you do 12 | not agree with these terms, please do not use, install, modify or 13 | redistribute this Apple software. 14 | 15 | In consideration of your agreement to abide by the following terms, and 16 | subject to these terms, Apple grants you a personal, non-exclusive 17 | license, under Apple's copyrights in this original Apple software (the 18 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 19 | Software, with or without modifications, in source and/or binary forms; 20 | provided that if you redistribute the Apple Software in its entirety and 21 | without modifications, you must retain this notice and the following 22 | text and disclaimers in all such redistributions of the Apple Software. 23 | Neither the name, trademarks, service marks or logos of Apple Inc. may 24 | be used to endorse or promote products derived from the Apple Software 25 | without specific prior written permission from Apple. Except as 26 | expressly stated in this notice, no other rights or licenses, express or 27 | implied, are granted by Apple herein, including but not limited to any 28 | patent rights that may be infringed by your derivative works or by other 29 | works in which the Apple Software may be incorporated. 30 | 31 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 32 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 33 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 34 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 35 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 36 | 37 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 38 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 41 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 42 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 43 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 44 | POSSIBILITY OF SUCH DAMAGE. 45 | 46 | Copyright (C) 2010 Apple Inc. All Rights Reserved. 47 | 48 | */ 49 | 50 | #import 51 | 52 | /* 53 | The KeychainItemWrapper class is an abstraction layer for the iPhone Keychain communication. It is merely a 54 | simple wrapper to provide a distinct barrier between all the idiosyncracies involved with the Keychain 55 | CF/NS container objects. 56 | */ 57 | @interface KeychainItemWrapper : NSObject 58 | 59 | // Designated initializer. 60 | - (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *)accessGroup; 61 | - (void)setObject:(id)inObject forKey:(id)key; 62 | - (id)objectForKey:(id)key; 63 | 64 | // Initializes and resets the default generic keychain item data. 65 | - (void)resetKeychainItem; 66 | 67 | @end -------------------------------------------------------------------------------- /SharingViaKeychain/SharedDataLayer/KeychainItemWrapper.m: -------------------------------------------------------------------------------- 1 | /* 2 | File: KeychainItemWrapper.m 3 | Abstract: 4 | Objective-C wrapper for accessing a single keychain item. 5 | 6 | Version: 1.2 - ARCified 7 | 8 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 9 | Inc. ("Apple") in consideration of your agreement to the following 10 | terms, and your use, installation, modification or redistribution of 11 | this Apple software constitutes acceptance of these terms. If you do 12 | not agree with these terms, please do not use, install, modify or 13 | redistribute this Apple software. 14 | 15 | In consideration of your agreement to abide by the following terms, and 16 | subject to these terms, Apple grants you a personal, non-exclusive 17 | license, under Apple's copyrights in this original Apple software (the 18 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 19 | Software, with or without modifications, in source and/or binary forms; 20 | provided that if you redistribute the Apple Software in its entirety and 21 | without modifications, you must retain this notice and the following 22 | text and disclaimers in all such redistributions of the Apple Software. 23 | Neither the name, trademarks, service marks or logos of Apple Inc. may 24 | be used to endorse or promote products derived from the Apple Software 25 | without specific prior written permission from Apple. Except as 26 | expressly stated in this notice, no other rights or licenses, express or 27 | implied, are granted by Apple herein, including but not limited to any 28 | patent rights that may be infringed by your derivative works or by other 29 | works in which the Apple Software may be incorporated. 30 | 31 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 32 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 33 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 34 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 35 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 36 | 37 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 38 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 39 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 40 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 41 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 42 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 43 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 44 | POSSIBILITY OF SUCH DAMAGE. 45 | 46 | Copyright (C) 2010 Apple Inc. All Rights Reserved. 47 | 48 | */ 49 | 50 | #define PASSWORD_USES_DATA 51 | 52 | #import "KeychainItemWrapper.h" 53 | #import 54 | 55 | /* 56 | 57 | These are the default constants and their respective types, 58 | available for the kSecClassGenericPassword Keychain Item class: 59 | 60 | kSecAttrAccessGroup - CFStringRef 61 | kSecAttrCreationDate - CFDateRef 62 | kSecAttrModificationDate - CFDateRef 63 | kSecAttrDescription - CFStringRef 64 | kSecAttrComment - CFStringRef 65 | kSecAttrCreator - CFNumberRef 66 | kSecAttrType - CFNumberRef 67 | kSecAttrLabel - CFStringRef 68 | kSecAttrIsInvisible - CFBooleanRef 69 | kSecAttrIsNegative - CFBooleanRef 70 | kSecAttrAccount - CFStringRef 71 | kSecAttrService - CFStringRef 72 | kSecAttrGeneric - CFDataRef 73 | 74 | See the header file Security/SecItem.h for more details. 75 | 76 | */ 77 | 78 | @interface KeychainItemWrapper (PrivateMethods) 79 | /* 80 | The decision behind the following two methods (secItemFormatToDictionary and dictionaryToSecItemFormat) was 81 | to encapsulate the transition between what the detail view controller was expecting (NSString *) and what the 82 | Keychain API expects as a validly constructed container class. 83 | */ 84 | - (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert; 85 | - (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert; 86 | 87 | // Updates the item in the keychain, or adds it if it doesn't exist. 88 | - (void)writeToKeychain; 89 | 90 | @end 91 | 92 | @implementation KeychainItemWrapper 93 | { 94 | NSMutableDictionary *keychainItemData; // The actual keychain item data backing store. 95 | NSMutableDictionary *genericPasswordQuery; // A placeholder for the generic keychain item query used to locate the item. 96 | } 97 | 98 | - (id)initWithIdentifier: (NSString *)identifier accessGroup:(NSString *) accessGroup; 99 | { 100 | if (self = [super init]) 101 | { 102 | // Begin Keychain search setup. The genericPasswordQuery leverages the special user 103 | // defined attribute kSecAttrGeneric to distinguish itself between other generic Keychain 104 | // items which may be included by the same application. 105 | genericPasswordQuery = [[NSMutableDictionary alloc] init]; 106 | 107 | [genericPasswordQuery setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; 108 | [genericPasswordQuery setObject:identifier forKey:(__bridge id)kSecAttrGeneric]; 109 | 110 | // The keychain access group attribute determines if this item can be shared 111 | // amongst multiple apps whose code signing entitlements contain the same keychain access group. 112 | if (accessGroup != nil) 113 | { 114 | #if TARGET_IPHONE_SIMULATOR 115 | // Ignore the access group if running on the iPhone simulator. 116 | // 117 | // Apps that are built for the simulator aren't signed, so there's no keychain access group 118 | // for the simulator to check. This means that all apps can see all keychain items when run 119 | // on the simulator. 120 | // 121 | // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the 122 | // simulator will return -25243 (errSecNoAccessForItem). 123 | #else 124 | [genericPasswordQuery setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup]; 125 | #endif 126 | } 127 | 128 | // Use the proper search constants, return only the attributes of the first match. 129 | [genericPasswordQuery setObject:(__bridge id)kSecMatchLimitOne forKey:(__bridge id)kSecMatchLimit]; 130 | [genericPasswordQuery setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnAttributes]; 131 | 132 | NSDictionary *tempQuery = [NSDictionary dictionaryWithDictionary:genericPasswordQuery]; 133 | 134 | CFMutableDictionaryRef outDictionary = NULL; 135 | 136 | if (!SecItemCopyMatching((__bridge CFDictionaryRef)tempQuery, (CFTypeRef *)&outDictionary) == noErr) 137 | { 138 | // Stick these default values into keychain item if nothing found. 139 | [self resetKeychainItem]; 140 | 141 | // Add the generic attribute and the keychain access group. 142 | [keychainItemData setObject:identifier forKey:(__bridge id)kSecAttrGeneric]; 143 | if (accessGroup != nil) 144 | { 145 | #if TARGET_IPHONE_SIMULATOR 146 | // Ignore the access group if running on the iPhone simulator. 147 | // 148 | // Apps that are built for the simulator aren't signed, so there's no keychain access group 149 | // for the simulator to check. This means that all apps can see all keychain items when run 150 | // on the simulator. 151 | // 152 | // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the 153 | // simulator will return -25243 (errSecNoAccessForItem). 154 | #else 155 | [keychainItemData setObject:accessGroup forKey:(__bridge id)kSecAttrAccessGroup]; 156 | #endif 157 | } 158 | } 159 | else 160 | { 161 | // load the saved data from Keychain. 162 | keychainItemData = [self secItemFormatToDictionary:(__bridge NSDictionary *)outDictionary]; 163 | } 164 | if(outDictionary) CFRelease(outDictionary); 165 | } 166 | 167 | return self; 168 | } 169 | 170 | - (void)setObject:(id)inObject forKey:(id)key 171 | { 172 | if (inObject == nil) return; 173 | id currentObject = [keychainItemData objectForKey:key]; 174 | if (![currentObject isEqual:inObject]) 175 | { 176 | [keychainItemData setObject:inObject forKey:key]; 177 | [self writeToKeychain]; 178 | } 179 | } 180 | 181 | - (id)objectForKey:(id)key 182 | { 183 | return [keychainItemData objectForKey:key]; 184 | } 185 | 186 | - (void)resetKeychainItem 187 | { 188 | if (!keychainItemData) 189 | { 190 | keychainItemData = [[NSMutableDictionary alloc] init]; 191 | } 192 | else if (keychainItemData) 193 | { 194 | NSMutableDictionary *tempDictionary = [self dictionaryToSecItemFormat:keychainItemData]; 195 | #ifndef NS_BLOCK_ASSERTIONS 196 | OSStatus junk = 197 | #endif 198 | SecItemDelete((__bridge CFDictionaryRef)tempDictionary); 199 | NSAssert( junk == noErr || junk == errSecItemNotFound, @"Problem deleting current dictionary." ); 200 | } 201 | 202 | // Default attributes for keychain item. 203 | [keychainItemData setObject:@"" forKey:(__bridge id)kSecAttrAccount]; 204 | [keychainItemData setObject:@"" forKey:(__bridge id)kSecAttrLabel]; 205 | [keychainItemData setObject:@"" forKey:(__bridge id)kSecAttrDescription]; 206 | 207 | // Default data for keychain item. 208 | #ifndef PASSWORD_USES_DATA 209 | [keychainItemData setObject:@"" forKey:(__bridge id)kSecValueData]; 210 | #else 211 | [keychainItemData setObject:[NSData data] forKey:(__bridge id)kSecValueData]; 212 | #endif 213 | } 214 | 215 | - (NSMutableDictionary *)dictionaryToSecItemFormat:(NSDictionary *)dictionaryToConvert 216 | { 217 | // The assumption is that this method will be called with a properly populated dictionary 218 | // containing all the right key/value pairs for a SecItem. 219 | 220 | // Create a dictionary to return populated with the attributes and data. 221 | NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert]; 222 | 223 | // Add the Generic Password keychain item class attribute. 224 | [returnDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; 225 | 226 | // Convert the NSString to NSData to meet the requirements for the value type kSecValueData. 227 | // This is where to store sensitive data that should be encrypted. 228 | #ifndef PASSWORD_USES_DATA 229 | // orig 230 | NSString *passwordString = [dictionaryToConvert objectForKey:(__bridge id)kSecValueData]; 231 | [returnDictionary setObject:[passwordString dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge id)kSecValueData]; 232 | #else 233 | // DFH 234 | id val = [dictionaryToConvert objectForKey:(__bridge id)kSecValueData]; 235 | if([val isKindOfClass:[NSString class]]) { 236 | val = [(NSString *)val dataUsingEncoding:NSUTF8StringEncoding]; 237 | } 238 | [returnDictionary setObject:val forKey:(__bridge id)kSecValueData]; 239 | #endif 240 | 241 | 242 | return returnDictionary; 243 | } 244 | 245 | - (NSMutableDictionary *)secItemFormatToDictionary:(NSDictionary *)dictionaryToConvert 246 | { 247 | // The assumption is that this method will be called with a properly populated dictionary 248 | // containing all the right key/value pairs for the UI element. 249 | 250 | // Create a dictionary to return populated with the attributes and data. 251 | NSMutableDictionary *returnDictionary = [NSMutableDictionary dictionaryWithDictionary:dictionaryToConvert]; 252 | 253 | // Add the proper search key and class attribute. 254 | [returnDictionary setObject:(__bridge id)kCFBooleanTrue forKey:(__bridge id)kSecReturnData]; 255 | [returnDictionary setObject:(__bridge id)kSecClassGenericPassword forKey:(__bridge id)kSecClass]; 256 | 257 | // Acquire the password data from the attributes. 258 | CFDataRef passwordData = NULL; 259 | if (SecItemCopyMatching((__bridge CFDictionaryRef)returnDictionary, (CFTypeRef *)&passwordData) == noErr) 260 | { 261 | // Remove the search, class, and identifier key/value, we don't need them anymore. 262 | [returnDictionary removeObjectForKey:(__bridge id)kSecReturnData]; 263 | 264 | #ifndef PASSWORD_USES_DATA 265 | // Add the password to the dictionary, converting from NSData to NSString. 266 | NSString *password = [[NSString alloc] initWithBytes:[(__bridge NSData *)passwordData bytes] length:[(__bridge NSData *)passwordData length] 267 | encoding:NSUTF8StringEncoding]; 268 | #else 269 | NSData *password = (__bridge_transfer NSData *)passwordData; 270 | passwordData = NULL; 271 | #endif 272 | [returnDictionary setObject:password forKey:(__bridge id)kSecValueData]; 273 | } 274 | else 275 | { 276 | // Don't do anything if nothing is found. 277 | NSAssert(NO, @"Serious error, no matching item found in the keychain.\n"); 278 | } 279 | if(passwordData) CFRelease(passwordData); 280 | 281 | return returnDictionary; 282 | } 283 | 284 | - (void)writeToKeychain 285 | { 286 | CFDictionaryRef attributes = NULL; 287 | NSMutableDictionary *updateItem = nil; 288 | OSStatus result; 289 | 290 | if (SecItemCopyMatching((__bridge CFDictionaryRef)genericPasswordQuery, (CFTypeRef *)&attributes) == noErr) 291 | { 292 | // First we need the attributes from the Keychain. 293 | updateItem = [NSMutableDictionary dictionaryWithDictionary:(__bridge NSDictionary *)attributes]; 294 | // Second we need to add the appropriate search key/values. 295 | [updateItem setObject:[genericPasswordQuery objectForKey:(__bridge id)kSecClass] forKey:(__bridge id)kSecClass]; 296 | 297 | // Lastly, we need to set up the updated attribute list being careful to remove the class. 298 | NSMutableDictionary *tempCheck = [self dictionaryToSecItemFormat:keychainItemData]; 299 | [tempCheck removeObjectForKey:(__bridge id)kSecClass]; 300 | 301 | #if TARGET_IPHONE_SIMULATOR 302 | // Remove the access group if running on the iPhone simulator. 303 | // 304 | // Apps that are built for the simulator aren't signed, so there's no keychain access group 305 | // for the simulator to check. This means that all apps can see all keychain items when run 306 | // on the simulator. 307 | // 308 | // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the 309 | // simulator will return -25243 (errSecNoAccessForItem). 310 | // 311 | // The access group attribute will be included in items returned by SecItemCopyMatching, 312 | // which is why we need to remove it before updating the item. 313 | [tempCheck removeObjectForKey:(__bridge id)kSecAttrAccessGroup]; 314 | #endif 315 | 316 | // An implicit assumption is that you can only update a single item at a time. 317 | #ifndef NDEBUG 318 | result = 319 | #endif 320 | SecItemUpdate((__bridge CFDictionaryRef)updateItem, (__bridge CFDictionaryRef)tempCheck); 321 | 322 | NSAssert( result == noErr, @"Couldn't update the Keychain Item." ); 323 | } 324 | else 325 | { 326 | // No previous item found; add the new one. 327 | result = SecItemAdd((__bridge CFDictionaryRef)[self dictionaryToSecItemFormat:keychainItemData], NULL); 328 | NSAssert( result == noErr, @"Couldn't add the Keychain Item." ); 329 | } 330 | 331 | if(attributes) CFRelease(attributes); 332 | } 333 | 334 | @end -------------------------------------------------------------------------------- /SharingViaKeychain/SharedDataLayer/SharedDataLayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SharedDataLayer.h 3 | // SharedDataLayer 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for SharedDataLayer. 12 | FOUNDATION_EXPORT double SharedDataLayerVersionNumber; 13 | 14 | //! Project version string for SharedDataLayer. 15 | FOUNDATION_EXPORT const unsigned char SharedDataLayerVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | #import 20 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharedDataLayerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharedDataLayerTests/SharedDataLayerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SharedDataLayerTests.m 3 | // SharedDataLayerTests 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SharedDataLayerTests : XCTestCase 13 | 14 | @end 15 | 16 | @implementation SharedDataLayerTests 17 | 18 | - (void)setUp { 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 | // Put teardown code here. This method is called after the invocation of each test method in the class. 25 | [super tearDown]; 26 | } 27 | 28 | - (void)testExample { 29 | // This is an example of a functional test case. 30 | XCTAssert(YES, @"Pass"); 31 | } 32 | 33 | - (void)testPerformanceExample { 34 | // This is an example of a performance test case. 35 | [self measureBlock:^{ 36 | // Put the code you want to measure the time of here. 37 | }]; 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 18 | 20 | 21 | 22 | 23 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "appLauncher", 41 | "subtype" : "42mm" 42 | }, 43 | { 44 | "size" : "86x86", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "38mm" 49 | }, 50 | { 51 | "size" : "98x98", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "42mm" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingViaKeychain 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingViaKeychain.watchkitapp 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 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | com.natashatherobot.SharingViaKeychain 32 | WKWatchKitApp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit Extension/Images.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingViaKeychain WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingViaKeychain.watchkitextension 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | com.natashatherobot.SharingViaKeychain.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | $(PRODUCT_MODULE_NAME).InterfaceController 37 | 38 | 39 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.swift 3 | // SharingViaKeychain WatchKit Extension 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import SharedDataLayer 11 | 12 | class InterfaceController: WKInterfaceController { 13 | 14 | @IBOutlet weak var usernameLabel: WKInterfaceLabel! 15 | @IBOutlet weak var passwordLabel: WKInterfaceLabel! 16 | 17 | 18 | override func awakeWithContext(context: AnyObject?) { 19 | super.awakeWithContext(context) 20 | 21 | let keychainItem = KeychainItemWrapper(identifier: "SharingViaKeychain", accessGroup: "W6GNU64U6Q.com.natashatherobot.SharingViaKeychain") 22 | 23 | 24 | let passwordData = keychainItem.objectForKey(kSecValueData) as NSData 25 | let password = NSString(data: passwordData, encoding: NSUTF8StringEncoding) 26 | 27 | let username = keychainItem.objectForKey(kSecAttrAccount) as? String 28 | 29 | switch (username, password) { 30 | case (.Some(let username), .Some(let password)): 31 | usernameLabel.setText(username) 32 | passwordLabel.setText(password) 33 | default: 34 | return 35 | } 36 | } 37 | } 38 | 39 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit Extension/PushNotificationPayload.apns: -------------------------------------------------------------------------------- 1 | { 2 | "aps": { 3 | "alert": { 4 | "body": "Test message", 5 | "title": "Optional title" 6 | }, 7 | "category": "myCategory" 8 | }, 9 | 10 | "WatchKit Simulator Actions": [ 11 | { 12 | "title": "First Button", 13 | "identifier": "firstButtonAction" 14 | } 15 | ], 16 | 17 | "customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App." 18 | } 19 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit Extension/SharingViaKeychain WatchKit Extension-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain WatchKit Extension/SharingViaKeychain WatchKit Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | keychain-access-groups 6 | 7 | $(AppIdentifierPrefix)W6GNU64U6Q.com.natashatherobot.SharingViaKeychain 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SharingViaKeychain 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // 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. 24 | // 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. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 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 | func applicationDidBecomeActive(application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/Base.lproj/Main.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 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/SharingViaKeychain-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | 5 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/SharingViaKeychain.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | keychain-access-groups 6 | 7 | $(AppIdentifierPrefix)W6GNU64U6Q.com.natashatherobot.SharingViaKeychain 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychain/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SharingViaKeychain 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SharedDataLayer 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var usernameTextField: UITextField! 15 | @IBOutlet weak var passwordTextField: UITextField! 16 | 17 | 18 | override func viewDidLoad() { 19 | super.viewDidLoad() 20 | } 21 | 22 | @IBAction func onSaveTap(sender: AnyObject) { 23 | 24 | let username = usernameTextField.text 25 | let password = passwordTextField.text 26 | 27 | let keychainItem = KeychainItemWrapper(identifier: "SharingViaKeychain", accessGroup: "W6GNU64U6Q.com.natashatherobot.SharingViaKeychain") 28 | 29 | keychainItem.setObject(username, forKey: kSecAttrAccount) 30 | keychainItem.setObject(password, forKey: kSecValueData) 31 | 32 | usernameTextField.text = nil 33 | passwordTextField.text = nil 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychainTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SharingViaKeychain/SharingViaKeychainTests/SharingViaKeychainTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SharingViaKeychainTests.swift 3 | // SharingViaKeychainTests 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class SharingViaKeychainTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NatashaTheRobot/watchkit/3e05c122b289bfcfcd57cd2f1405cf19b61b1546/SharingWithFileCoordinator/.DS_Store -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 |
28 | 29 | 30 | 31 | 32 |
33 |
34 |
35 |
36 |
37 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "appLauncher", 41 | "subtype" : "42mm" 42 | }, 43 | { 44 | "size" : "86x86", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "38mm" 49 | }, 50 | { 51 | "size" : "98x98", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "42mm" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingWithFileCoordinator 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingWithFileCoordinator.watchkitapp 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 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | com.natashatherobot.SharingWithFileCoordinator 32 | WKWatchKitApp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit Extension/Images.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingWithFileCoordinator WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingWithFileCoordinator.watchkitextension 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | com.natashatherobot.SharingWithFileCoordinator.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | $(PRODUCT_MODULE_NAME).InterfaceController 37 | 38 | 39 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.swift 3 | // SharingWithFileCoordinator WatchKit Extension 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import Foundation 11 | 12 | class InterfaceController: WKInterfaceController { 13 | 14 | @IBOutlet weak private var todoItemsTable: WKInterfaceTable! 15 | 16 | var todoItems = [String]() 17 | 18 | override func awakeWithContext(context: AnyObject?) { 19 | super.awakeWithContext(context) 20 | 21 | NSFileCoordinator.addFilePresenter(self) 22 | 23 | fetchTodoItems() 24 | } 25 | 26 | // MARK: Populate Table From File Coordinator 27 | 28 | private func fetchTodoItems() { 29 | 30 | let fileCoordinator = NSFileCoordinator() 31 | 32 | if let presentedItemURL = presentedItemURL { 33 | 34 | fileCoordinator.coordinateReadingItemAtURL(presentedItemURL, options: nil, error: nil) 35 | { [unowned self] (newURL) -> Void in 36 | 37 | if let savedData = NSData(contentsOfURL: newURL) { 38 | self.todoItems = NSKeyedUnarchiver.unarchiveObjectWithData(savedData) as [String] 39 | self.populateTableWithTodoItems(self.todoItems) 40 | } 41 | } 42 | } 43 | } 44 | 45 | private func populateTableWithTodoItems(items: [String]) { 46 | self.todoItemsTable.setNumberOfRows(self.todoItems.count, withRowType: "TodoTableRowController") 47 | 48 | for (index, todoItem) in enumerate(self.todoItems) { 49 | if let row = self.todoItemsTable.rowControllerAtIndex(index) as? TodoTableRowController { 50 | row.todoItemLabel.setText(todoItem) 51 | } 52 | 53 | } 54 | } 55 | 56 | } 57 | 58 | // MARK: NSFilePresenter Protocol 59 | 60 | extension InterfaceController: NSFilePresenter { 61 | 62 | var presentedItemURL: NSURL? { 63 | 64 | let groupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier( 65 | "group.com.natashatherobot.watchlist") 66 | 67 | let fileURL = groupURL?.URLByAppendingPathComponent("todoItems.bin") 68 | return fileURL 69 | } 70 | 71 | var presentedItemOperationQueue: NSOperationQueue { 72 | return NSOperationQueue.mainQueue() 73 | } 74 | 75 | func presentedItemDidChange() { 76 | fetchTodoItems() 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit Extension/SharingWithFileCoordinator WatchKit Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.natashatherobot.watchlist 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator WatchKit Extension/TodoTableRowController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodoTableRowController.swift 3 | // SharingWithFileCoordinator 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | 11 | class TodoTableRowController: NSObject { 12 | 13 | @IBOutlet weak var todoItemLabel: WKInterfaceLabel! 14 | } 15 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FA696A851A82921300E81513 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696A841A82921300E81513 /* AppDelegate.swift */; }; 11 | FA696A8A1A82921300E81513 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA696A881A82921300E81513 /* Main.storyboard */; }; 12 | FA696A8C1A82921300E81513 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA696A8B1A82921300E81513 /* Images.xcassets */; }; 13 | FA696A8F1A82921300E81513 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA696A8D1A82921300E81513 /* LaunchScreen.xib */; }; 14 | FA696A9B1A82921300E81513 /* SharingWithFileCoordinatorTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696A9A1A82921300E81513 /* SharingWithFileCoordinatorTests.swift */; }; 15 | FA696AAD1A82BD5F00E81513 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696AAC1A82BD5F00E81513 /* InterfaceController.swift */; }; 16 | FA696AAF1A82BD5F00E81513 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA696AAE1A82BD5F00E81513 /* Images.xcassets */; }; 17 | FA696AB31A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App.app in Resources */ = {isa = PBXBuildFile; fileRef = FA696AB21A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App.app */; }; 18 | FA696ABB1A82BD5F00E81513 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA696AB91A82BD5F00E81513 /* Interface.storyboard */; }; 19 | FA696ABD1A82BD5F00E81513 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA696ABC1A82BD5F00E81513 /* Images.xcassets */; }; 20 | FA696AC01A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = FA696AA81A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 21 | FA696ACB1A82C0A900E81513 /* TodoListTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696ACA1A82C0A900E81513 /* TodoListTableViewController.swift */; }; 22 | FA696ACD1A82C0E000E81513 /* InputTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696ACC1A82C0E000E81513 /* InputTableViewCell.swift */; }; 23 | FA696ACF1A82D30800E81513 /* TodoTableRowController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696ACE1A82D30800E81513 /* TodoTableRowController.swift */; }; 24 | /* End PBXBuildFile section */ 25 | 26 | /* Begin PBXContainerItemProxy section */ 27 | FA696A951A82921300E81513 /* PBXContainerItemProxy */ = { 28 | isa = PBXContainerItemProxy; 29 | containerPortal = FA696A771A82921300E81513 /* Project object */; 30 | proxyType = 1; 31 | remoteGlobalIDString = FA696A7E1A82921300E81513; 32 | remoteInfo = SharingWithFileCoordinator; 33 | }; 34 | FA696AB41A82BD5F00E81513 /* PBXContainerItemProxy */ = { 35 | isa = PBXContainerItemProxy; 36 | containerPortal = FA696A771A82921300E81513 /* Project object */; 37 | proxyType = 1; 38 | remoteGlobalIDString = FA696AB11A82BD5F00E81513; 39 | remoteInfo = "SharingWithFileCoordinator WatchKit App"; 40 | }; 41 | FA696ABE1A82BD5F00E81513 /* PBXContainerItemProxy */ = { 42 | isa = PBXContainerItemProxy; 43 | containerPortal = FA696A771A82921300E81513 /* Project object */; 44 | proxyType = 1; 45 | remoteGlobalIDString = FA696AA71A82BD5F00E81513; 46 | remoteInfo = "SharingWithFileCoordinator WatchKit Extension"; 47 | }; 48 | /* End PBXContainerItemProxy section */ 49 | 50 | /* Begin PBXCopyFilesBuildPhase section */ 51 | FA696AC71A82BD5F00E81513 /* Embed App Extensions */ = { 52 | isa = PBXCopyFilesBuildPhase; 53 | buildActionMask = 2147483647; 54 | dstPath = ""; 55 | dstSubfolderSpec = 13; 56 | files = ( 57 | FA696AC01A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension.appex in Embed App Extensions */, 58 | ); 59 | name = "Embed App Extensions"; 60 | runOnlyForDeploymentPostprocessing = 0; 61 | }; 62 | /* End PBXCopyFilesBuildPhase section */ 63 | 64 | /* Begin PBXFileReference section */ 65 | FA696A7F1A82921300E81513 /* SharingWithFileCoordinator.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SharingWithFileCoordinator.app; sourceTree = BUILT_PRODUCTS_DIR; }; 66 | FA696A831A82921300E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 67 | FA696A841A82921300E81513 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 68 | FA696A891A82921300E81513 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 69 | FA696A8B1A82921300E81513 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 70 | FA696A8E1A82921300E81513 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 71 | FA696A941A82921300E81513 /* SharingWithFileCoordinatorTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SharingWithFileCoordinatorTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 72 | FA696A991A82921300E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 73 | FA696A9A1A82921300E81513 /* SharingWithFileCoordinatorTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingWithFileCoordinatorTests.swift; sourceTree = ""; }; 74 | FA696AA81A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SharingWithFileCoordinator WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | FA696AAB1A82BD5F00E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 76 | FA696AAC1A82BD5F00E81513 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = ""; }; 77 | FA696AAE1A82BD5F00E81513 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 78 | FA696AB21A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SharingWithFileCoordinator WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | FA696AB81A82BD5F00E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 80 | FA696ABA1A82BD5F00E81513 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; 81 | FA696ABC1A82BD5F00E81513 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 82 | FA696AC81A82BD6B00E81513 /* SharingWithFileCoordinator.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = SharingWithFileCoordinator.entitlements; sourceTree = ""; }; 83 | FA696AC91A82BD9300E81513 /* SharingWithFileCoordinator WatchKit Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "SharingWithFileCoordinator WatchKit Extension.entitlements"; sourceTree = ""; }; 84 | FA696ACA1A82C0A900E81513 /* TodoListTableViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TodoListTableViewController.swift; sourceTree = ""; }; 85 | FA696ACC1A82C0E000E81513 /* InputTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InputTableViewCell.swift; sourceTree = ""; }; 86 | FA696ACE1A82D30800E81513 /* TodoTableRowController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TodoTableRowController.swift; sourceTree = ""; }; 87 | /* End PBXFileReference section */ 88 | 89 | /* Begin PBXFrameworksBuildPhase section */ 90 | FA696A7C1A82921300E81513 /* Frameworks */ = { 91 | isa = PBXFrameworksBuildPhase; 92 | buildActionMask = 2147483647; 93 | files = ( 94 | ); 95 | runOnlyForDeploymentPostprocessing = 0; 96 | }; 97 | FA696A911A82921300E81513 /* Frameworks */ = { 98 | isa = PBXFrameworksBuildPhase; 99 | buildActionMask = 2147483647; 100 | files = ( 101 | ); 102 | runOnlyForDeploymentPostprocessing = 0; 103 | }; 104 | FA696AA51A82BD5F00E81513 /* Frameworks */ = { 105 | isa = PBXFrameworksBuildPhase; 106 | buildActionMask = 2147483647; 107 | files = ( 108 | ); 109 | runOnlyForDeploymentPostprocessing = 0; 110 | }; 111 | /* End PBXFrameworksBuildPhase section */ 112 | 113 | /* Begin PBXGroup section */ 114 | FA696A761A82921300E81513 = { 115 | isa = PBXGroup; 116 | children = ( 117 | FA696A811A82921300E81513 /* SharingWithFileCoordinator */, 118 | FA696A971A82921300E81513 /* SharingWithFileCoordinatorTests */, 119 | FA696AA91A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension */, 120 | FA696AB61A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App */, 121 | FA696A801A82921300E81513 /* Products */, 122 | ); 123 | sourceTree = ""; 124 | }; 125 | FA696A801A82921300E81513 /* Products */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | FA696A7F1A82921300E81513 /* SharingWithFileCoordinator.app */, 129 | FA696A941A82921300E81513 /* SharingWithFileCoordinatorTests.xctest */, 130 | FA696AA81A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension.appex */, 131 | FA696AB21A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App.app */, 132 | ); 133 | name = Products; 134 | sourceTree = ""; 135 | }; 136 | FA696A811A82921300E81513 /* SharingWithFileCoordinator */ = { 137 | isa = PBXGroup; 138 | children = ( 139 | FA696AC81A82BD6B00E81513 /* SharingWithFileCoordinator.entitlements */, 140 | FA696A841A82921300E81513 /* AppDelegate.swift */, 141 | FA696A881A82921300E81513 /* Main.storyboard */, 142 | FA696ACA1A82C0A900E81513 /* TodoListTableViewController.swift */, 143 | FA696ACC1A82C0E000E81513 /* InputTableViewCell.swift */, 144 | FA696A8B1A82921300E81513 /* Images.xcassets */, 145 | FA696A8D1A82921300E81513 /* LaunchScreen.xib */, 146 | FA696A821A82921300E81513 /* Supporting Files */, 147 | ); 148 | path = SharingWithFileCoordinator; 149 | sourceTree = ""; 150 | }; 151 | FA696A821A82921300E81513 /* Supporting Files */ = { 152 | isa = PBXGroup; 153 | children = ( 154 | FA696A831A82921300E81513 /* Info.plist */, 155 | ); 156 | name = "Supporting Files"; 157 | sourceTree = ""; 158 | }; 159 | FA696A971A82921300E81513 /* SharingWithFileCoordinatorTests */ = { 160 | isa = PBXGroup; 161 | children = ( 162 | FA696A9A1A82921300E81513 /* SharingWithFileCoordinatorTests.swift */, 163 | FA696A981A82921300E81513 /* Supporting Files */, 164 | ); 165 | path = SharingWithFileCoordinatorTests; 166 | sourceTree = ""; 167 | }; 168 | FA696A981A82921300E81513 /* Supporting Files */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | FA696A991A82921300E81513 /* Info.plist */, 172 | ); 173 | name = "Supporting Files"; 174 | sourceTree = ""; 175 | }; 176 | FA696AA91A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | FA696AC91A82BD9300E81513 /* SharingWithFileCoordinator WatchKit Extension.entitlements */, 180 | FA696AAC1A82BD5F00E81513 /* InterfaceController.swift */, 181 | FA696ACE1A82D30800E81513 /* TodoTableRowController.swift */, 182 | FA696AAE1A82BD5F00E81513 /* Images.xcassets */, 183 | FA696AAA1A82BD5F00E81513 /* Supporting Files */, 184 | ); 185 | path = "SharingWithFileCoordinator WatchKit Extension"; 186 | sourceTree = ""; 187 | }; 188 | FA696AAA1A82BD5F00E81513 /* Supporting Files */ = { 189 | isa = PBXGroup; 190 | children = ( 191 | FA696AAB1A82BD5F00E81513 /* Info.plist */, 192 | ); 193 | name = "Supporting Files"; 194 | sourceTree = ""; 195 | }; 196 | FA696AB61A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App */ = { 197 | isa = PBXGroup; 198 | children = ( 199 | FA696AB91A82BD5F00E81513 /* Interface.storyboard */, 200 | FA696ABC1A82BD5F00E81513 /* Images.xcassets */, 201 | FA696AB71A82BD5F00E81513 /* Supporting Files */, 202 | ); 203 | path = "SharingWithFileCoordinator WatchKit App"; 204 | sourceTree = ""; 205 | }; 206 | FA696AB71A82BD5F00E81513 /* Supporting Files */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | FA696AB81A82BD5F00E81513 /* Info.plist */, 210 | ); 211 | name = "Supporting Files"; 212 | sourceTree = ""; 213 | }; 214 | /* End PBXGroup section */ 215 | 216 | /* Begin PBXNativeTarget section */ 217 | FA696A7E1A82921300E81513 /* SharingWithFileCoordinator */ = { 218 | isa = PBXNativeTarget; 219 | buildConfigurationList = FA696A9E1A82921300E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinator" */; 220 | buildPhases = ( 221 | FA696A7B1A82921300E81513 /* Sources */, 222 | FA696A7C1A82921300E81513 /* Frameworks */, 223 | FA696A7D1A82921300E81513 /* Resources */, 224 | FA696AC71A82BD5F00E81513 /* Embed App Extensions */, 225 | ); 226 | buildRules = ( 227 | ); 228 | dependencies = ( 229 | FA696ABF1A82BD5F00E81513 /* PBXTargetDependency */, 230 | ); 231 | name = SharingWithFileCoordinator; 232 | productName = SharingWithFileCoordinator; 233 | productReference = FA696A7F1A82921300E81513 /* SharingWithFileCoordinator.app */; 234 | productType = "com.apple.product-type.application"; 235 | }; 236 | FA696A931A82921300E81513 /* SharingWithFileCoordinatorTests */ = { 237 | isa = PBXNativeTarget; 238 | buildConfigurationList = FA696AA11A82921300E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinatorTests" */; 239 | buildPhases = ( 240 | FA696A901A82921300E81513 /* Sources */, 241 | FA696A911A82921300E81513 /* Frameworks */, 242 | FA696A921A82921300E81513 /* Resources */, 243 | ); 244 | buildRules = ( 245 | ); 246 | dependencies = ( 247 | FA696A961A82921300E81513 /* PBXTargetDependency */, 248 | ); 249 | name = SharingWithFileCoordinatorTests; 250 | productName = SharingWithFileCoordinatorTests; 251 | productReference = FA696A941A82921300E81513 /* SharingWithFileCoordinatorTests.xctest */; 252 | productType = "com.apple.product-type.bundle.unit-test"; 253 | }; 254 | FA696AA71A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension */ = { 255 | isa = PBXNativeTarget; 256 | buildConfigurationList = FA696AC41A82BD5F00E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinator WatchKit Extension" */; 257 | buildPhases = ( 258 | FA696AA41A82BD5F00E81513 /* Sources */, 259 | FA696AA51A82BD5F00E81513 /* Frameworks */, 260 | FA696AA61A82BD5F00E81513 /* Resources */, 261 | ); 262 | buildRules = ( 263 | ); 264 | dependencies = ( 265 | FA696AB51A82BD5F00E81513 /* PBXTargetDependency */, 266 | ); 267 | name = "SharingWithFileCoordinator WatchKit Extension"; 268 | productName = "SharingWithFileCoordinator WatchKit Extension"; 269 | productReference = FA696AA81A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension.appex */; 270 | productType = "com.apple.product-type.watchkit-extension"; 271 | }; 272 | FA696AB11A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App */ = { 273 | isa = PBXNativeTarget; 274 | buildConfigurationList = FA696AC11A82BD5F00E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinator WatchKit App" */; 275 | buildPhases = ( 276 | FA696AB01A82BD5F00E81513 /* Resources */, 277 | ); 278 | buildRules = ( 279 | ); 280 | dependencies = ( 281 | ); 282 | name = "SharingWithFileCoordinator WatchKit App"; 283 | productName = "SharingWithFileCoordinator WatchKit App"; 284 | productReference = FA696AB21A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App.app */; 285 | productType = "com.apple.product-type.application.watchapp"; 286 | }; 287 | /* End PBXNativeTarget section */ 288 | 289 | /* Begin PBXProject section */ 290 | FA696A771A82921300E81513 /* Project object */ = { 291 | isa = PBXProject; 292 | attributes = { 293 | LastUpgradeCheck = 0620; 294 | ORGANIZATIONNAME = NatashaTheRobot; 295 | TargetAttributes = { 296 | FA696A7E1A82921300E81513 = { 297 | CreatedOnToolsVersion = 6.2; 298 | DevelopmentTeam = W6GNU64U6Q; 299 | SystemCapabilities = { 300 | com.apple.ApplicationGroups.iOS = { 301 | enabled = 1; 302 | }; 303 | }; 304 | }; 305 | FA696A931A82921300E81513 = { 306 | CreatedOnToolsVersion = 6.2; 307 | TestTargetID = FA696A7E1A82921300E81513; 308 | }; 309 | FA696AA71A82BD5F00E81513 = { 310 | CreatedOnToolsVersion = 6.2; 311 | DevelopmentTeam = W6GNU64U6Q; 312 | SystemCapabilities = { 313 | com.apple.ApplicationGroups.iOS = { 314 | enabled = 1; 315 | }; 316 | }; 317 | }; 318 | FA696AB11A82BD5F00E81513 = { 319 | CreatedOnToolsVersion = 6.2; 320 | }; 321 | }; 322 | }; 323 | buildConfigurationList = FA696A7A1A82921300E81513 /* Build configuration list for PBXProject "SharingWithFileCoordinator" */; 324 | compatibilityVersion = "Xcode 3.2"; 325 | developmentRegion = English; 326 | hasScannedForEncodings = 0; 327 | knownRegions = ( 328 | en, 329 | Base, 330 | ); 331 | mainGroup = FA696A761A82921300E81513; 332 | productRefGroup = FA696A801A82921300E81513 /* Products */; 333 | projectDirPath = ""; 334 | projectRoot = ""; 335 | targets = ( 336 | FA696A7E1A82921300E81513 /* SharingWithFileCoordinator */, 337 | FA696A931A82921300E81513 /* SharingWithFileCoordinatorTests */, 338 | FA696AA71A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension */, 339 | FA696AB11A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App */, 340 | ); 341 | }; 342 | /* End PBXProject section */ 343 | 344 | /* Begin PBXResourcesBuildPhase section */ 345 | FA696A7D1A82921300E81513 /* Resources */ = { 346 | isa = PBXResourcesBuildPhase; 347 | buildActionMask = 2147483647; 348 | files = ( 349 | FA696A8A1A82921300E81513 /* Main.storyboard in Resources */, 350 | FA696A8F1A82921300E81513 /* LaunchScreen.xib in Resources */, 351 | FA696A8C1A82921300E81513 /* Images.xcassets in Resources */, 352 | ); 353 | runOnlyForDeploymentPostprocessing = 0; 354 | }; 355 | FA696A921A82921300E81513 /* Resources */ = { 356 | isa = PBXResourcesBuildPhase; 357 | buildActionMask = 2147483647; 358 | files = ( 359 | ); 360 | runOnlyForDeploymentPostprocessing = 0; 361 | }; 362 | FA696AA61A82BD5F00E81513 /* Resources */ = { 363 | isa = PBXResourcesBuildPhase; 364 | buildActionMask = 2147483647; 365 | files = ( 366 | FA696AB31A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App.app in Resources */, 367 | FA696AAF1A82BD5F00E81513 /* Images.xcassets in Resources */, 368 | ); 369 | runOnlyForDeploymentPostprocessing = 0; 370 | }; 371 | FA696AB01A82BD5F00E81513 /* Resources */ = { 372 | isa = PBXResourcesBuildPhase; 373 | buildActionMask = 2147483647; 374 | files = ( 375 | FA696ABB1A82BD5F00E81513 /* Interface.storyboard in Resources */, 376 | FA696ABD1A82BD5F00E81513 /* Images.xcassets in Resources */, 377 | ); 378 | runOnlyForDeploymentPostprocessing = 0; 379 | }; 380 | /* End PBXResourcesBuildPhase section */ 381 | 382 | /* Begin PBXSourcesBuildPhase section */ 383 | FA696A7B1A82921300E81513 /* Sources */ = { 384 | isa = PBXSourcesBuildPhase; 385 | buildActionMask = 2147483647; 386 | files = ( 387 | FA696A851A82921300E81513 /* AppDelegate.swift in Sources */, 388 | FA696ACD1A82C0E000E81513 /* InputTableViewCell.swift in Sources */, 389 | FA696ACB1A82C0A900E81513 /* TodoListTableViewController.swift in Sources */, 390 | ); 391 | runOnlyForDeploymentPostprocessing = 0; 392 | }; 393 | FA696A901A82921300E81513 /* Sources */ = { 394 | isa = PBXSourcesBuildPhase; 395 | buildActionMask = 2147483647; 396 | files = ( 397 | FA696A9B1A82921300E81513 /* SharingWithFileCoordinatorTests.swift in Sources */, 398 | ); 399 | runOnlyForDeploymentPostprocessing = 0; 400 | }; 401 | FA696AA41A82BD5F00E81513 /* Sources */ = { 402 | isa = PBXSourcesBuildPhase; 403 | buildActionMask = 2147483647; 404 | files = ( 405 | FA696AAD1A82BD5F00E81513 /* InterfaceController.swift in Sources */, 406 | FA696ACF1A82D30800E81513 /* TodoTableRowController.swift in Sources */, 407 | ); 408 | runOnlyForDeploymentPostprocessing = 0; 409 | }; 410 | /* End PBXSourcesBuildPhase section */ 411 | 412 | /* Begin PBXTargetDependency section */ 413 | FA696A961A82921300E81513 /* PBXTargetDependency */ = { 414 | isa = PBXTargetDependency; 415 | target = FA696A7E1A82921300E81513 /* SharingWithFileCoordinator */; 416 | targetProxy = FA696A951A82921300E81513 /* PBXContainerItemProxy */; 417 | }; 418 | FA696AB51A82BD5F00E81513 /* PBXTargetDependency */ = { 419 | isa = PBXTargetDependency; 420 | target = FA696AB11A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit App */; 421 | targetProxy = FA696AB41A82BD5F00E81513 /* PBXContainerItemProxy */; 422 | }; 423 | FA696ABF1A82BD5F00E81513 /* PBXTargetDependency */ = { 424 | isa = PBXTargetDependency; 425 | target = FA696AA71A82BD5F00E81513 /* SharingWithFileCoordinator WatchKit Extension */; 426 | targetProxy = FA696ABE1A82BD5F00E81513 /* PBXContainerItemProxy */; 427 | }; 428 | /* End PBXTargetDependency section */ 429 | 430 | /* Begin PBXVariantGroup section */ 431 | FA696A881A82921300E81513 /* Main.storyboard */ = { 432 | isa = PBXVariantGroup; 433 | children = ( 434 | FA696A891A82921300E81513 /* Base */, 435 | ); 436 | name = Main.storyboard; 437 | sourceTree = ""; 438 | }; 439 | FA696A8D1A82921300E81513 /* LaunchScreen.xib */ = { 440 | isa = PBXVariantGroup; 441 | children = ( 442 | FA696A8E1A82921300E81513 /* Base */, 443 | ); 444 | name = LaunchScreen.xib; 445 | sourceTree = ""; 446 | }; 447 | FA696AB91A82BD5F00E81513 /* Interface.storyboard */ = { 448 | isa = PBXVariantGroup; 449 | children = ( 450 | FA696ABA1A82BD5F00E81513 /* Base */, 451 | ); 452 | name = Interface.storyboard; 453 | sourceTree = ""; 454 | }; 455 | /* End PBXVariantGroup section */ 456 | 457 | /* Begin XCBuildConfiguration section */ 458 | FA696A9C1A82921300E81513 /* Debug */ = { 459 | isa = XCBuildConfiguration; 460 | buildSettings = { 461 | ALWAYS_SEARCH_USER_PATHS = NO; 462 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 463 | CLANG_CXX_LIBRARY = "libc++"; 464 | CLANG_ENABLE_MODULES = YES; 465 | CLANG_ENABLE_OBJC_ARC = YES; 466 | CLANG_WARN_BOOL_CONVERSION = YES; 467 | CLANG_WARN_CONSTANT_CONVERSION = YES; 468 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 469 | CLANG_WARN_EMPTY_BODY = YES; 470 | CLANG_WARN_ENUM_CONVERSION = YES; 471 | CLANG_WARN_INT_CONVERSION = YES; 472 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 473 | CLANG_WARN_UNREACHABLE_CODE = YES; 474 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 475 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 476 | COPY_PHASE_STRIP = NO; 477 | ENABLE_STRICT_OBJC_MSGSEND = YES; 478 | GCC_C_LANGUAGE_STANDARD = gnu99; 479 | GCC_DYNAMIC_NO_PIC = NO; 480 | GCC_OPTIMIZATION_LEVEL = 0; 481 | GCC_PREPROCESSOR_DEFINITIONS = ( 482 | "DEBUG=1", 483 | "$(inherited)", 484 | ); 485 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 486 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 487 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 488 | GCC_WARN_UNDECLARED_SELECTOR = YES; 489 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 490 | GCC_WARN_UNUSED_FUNCTION = YES; 491 | GCC_WARN_UNUSED_VARIABLE = YES; 492 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 493 | MTL_ENABLE_DEBUG_INFO = YES; 494 | ONLY_ACTIVE_ARCH = YES; 495 | SDKROOT = iphoneos; 496 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 497 | }; 498 | name = Debug; 499 | }; 500 | FA696A9D1A82921300E81513 /* Release */ = { 501 | isa = XCBuildConfiguration; 502 | buildSettings = { 503 | ALWAYS_SEARCH_USER_PATHS = NO; 504 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 505 | CLANG_CXX_LIBRARY = "libc++"; 506 | CLANG_ENABLE_MODULES = YES; 507 | CLANG_ENABLE_OBJC_ARC = YES; 508 | CLANG_WARN_BOOL_CONVERSION = YES; 509 | CLANG_WARN_CONSTANT_CONVERSION = YES; 510 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 511 | CLANG_WARN_EMPTY_BODY = YES; 512 | CLANG_WARN_ENUM_CONVERSION = YES; 513 | CLANG_WARN_INT_CONVERSION = YES; 514 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 515 | CLANG_WARN_UNREACHABLE_CODE = YES; 516 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 517 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 518 | COPY_PHASE_STRIP = NO; 519 | ENABLE_NS_ASSERTIONS = NO; 520 | ENABLE_STRICT_OBJC_MSGSEND = YES; 521 | GCC_C_LANGUAGE_STANDARD = gnu99; 522 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 523 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 524 | GCC_WARN_UNDECLARED_SELECTOR = YES; 525 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 526 | GCC_WARN_UNUSED_FUNCTION = YES; 527 | GCC_WARN_UNUSED_VARIABLE = YES; 528 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 529 | MTL_ENABLE_DEBUG_INFO = NO; 530 | SDKROOT = iphoneos; 531 | VALIDATE_PRODUCT = YES; 532 | }; 533 | name = Release; 534 | }; 535 | FA696A9F1A82921300E81513 /* Debug */ = { 536 | isa = XCBuildConfiguration; 537 | buildSettings = { 538 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 539 | CODE_SIGN_ENTITLEMENTS = SharingWithFileCoordinator/SharingWithFileCoordinator.entitlements; 540 | CODE_SIGN_IDENTITY = "iPhone Developer"; 541 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 542 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 543 | INFOPLIST_FILE = SharingWithFileCoordinator/Info.plist; 544 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 545 | PRODUCT_NAME = "$(TARGET_NAME)"; 546 | PROVISIONING_PROFILE = ""; 547 | }; 548 | name = Debug; 549 | }; 550 | FA696AA01A82921300E81513 /* Release */ = { 551 | isa = XCBuildConfiguration; 552 | buildSettings = { 553 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 554 | CODE_SIGN_ENTITLEMENTS = SharingWithFileCoordinator/SharingWithFileCoordinator.entitlements; 555 | CODE_SIGN_IDENTITY = "iPhone Developer"; 556 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 557 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 558 | INFOPLIST_FILE = SharingWithFileCoordinator/Info.plist; 559 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 560 | PRODUCT_NAME = "$(TARGET_NAME)"; 561 | PROVISIONING_PROFILE = ""; 562 | }; 563 | name = Release; 564 | }; 565 | FA696AA21A82921300E81513 /* Debug */ = { 566 | isa = XCBuildConfiguration; 567 | buildSettings = { 568 | BUNDLE_LOADER = "$(TEST_HOST)"; 569 | FRAMEWORK_SEARCH_PATHS = ( 570 | "$(SDKROOT)/Developer/Library/Frameworks", 571 | "$(inherited)", 572 | ); 573 | GCC_PREPROCESSOR_DEFINITIONS = ( 574 | "DEBUG=1", 575 | "$(inherited)", 576 | ); 577 | INFOPLIST_FILE = SharingWithFileCoordinatorTests/Info.plist; 578 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 579 | PRODUCT_NAME = "$(TARGET_NAME)"; 580 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SharingWithFileCoordinator.app/SharingWithFileCoordinator"; 581 | }; 582 | name = Debug; 583 | }; 584 | FA696AA31A82921300E81513 /* Release */ = { 585 | isa = XCBuildConfiguration; 586 | buildSettings = { 587 | BUNDLE_LOADER = "$(TEST_HOST)"; 588 | FRAMEWORK_SEARCH_PATHS = ( 589 | "$(SDKROOT)/Developer/Library/Frameworks", 590 | "$(inherited)", 591 | ); 592 | INFOPLIST_FILE = SharingWithFileCoordinatorTests/Info.plist; 593 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 594 | PRODUCT_NAME = "$(TARGET_NAME)"; 595 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SharingWithFileCoordinator.app/SharingWithFileCoordinator"; 596 | }; 597 | name = Release; 598 | }; 599 | FA696AC21A82BD5F00E81513 /* Debug */ = { 600 | isa = XCBuildConfiguration; 601 | buildSettings = { 602 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 603 | GCC_PREPROCESSOR_DEFINITIONS = ( 604 | "DEBUG=1", 605 | "$(inherited)", 606 | ); 607 | IBSC_MODULE = SharingWithFileCoordinator_WatchKit_Extension; 608 | INFOPLIST_FILE = "SharingWithFileCoordinator WatchKit App/Info.plist"; 609 | PRODUCT_NAME = "$(TARGET_NAME)"; 610 | SKIP_INSTALL = YES; 611 | TARGETED_DEVICE_FAMILY = 4; 612 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4"; 613 | }; 614 | name = Debug; 615 | }; 616 | FA696AC31A82BD5F00E81513 /* Release */ = { 617 | isa = XCBuildConfiguration; 618 | buildSettings = { 619 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 620 | IBSC_MODULE = SharingWithFileCoordinator_WatchKit_Extension; 621 | INFOPLIST_FILE = "SharingWithFileCoordinator WatchKit App/Info.plist"; 622 | PRODUCT_NAME = "$(TARGET_NAME)"; 623 | SKIP_INSTALL = YES; 624 | TARGETED_DEVICE_FAMILY = 4; 625 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4"; 626 | }; 627 | name = Release; 628 | }; 629 | FA696AC51A82BD5F00E81513 /* Debug */ = { 630 | isa = XCBuildConfiguration; 631 | buildSettings = { 632 | CODE_SIGN_ENTITLEMENTS = "SharingWithFileCoordinator WatchKit Extension/SharingWithFileCoordinator WatchKit Extension.entitlements"; 633 | CODE_SIGN_IDENTITY = "iPhone Developer"; 634 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 635 | GCC_PREPROCESSOR_DEFINITIONS = ( 636 | "DEBUG=1", 637 | "$(inherited)", 638 | ); 639 | INFOPLIST_FILE = "SharingWithFileCoordinator WatchKit Extension/Info.plist"; 640 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 641 | PRODUCT_NAME = "${TARGET_NAME}"; 642 | PROVISIONING_PROFILE = ""; 643 | SKIP_INSTALL = YES; 644 | }; 645 | name = Debug; 646 | }; 647 | FA696AC61A82BD5F00E81513 /* Release */ = { 648 | isa = XCBuildConfiguration; 649 | buildSettings = { 650 | CODE_SIGN_ENTITLEMENTS = "SharingWithFileCoordinator WatchKit Extension/SharingWithFileCoordinator WatchKit Extension.entitlements"; 651 | CODE_SIGN_IDENTITY = "iPhone Developer"; 652 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 653 | INFOPLIST_FILE = "SharingWithFileCoordinator WatchKit Extension/Info.plist"; 654 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 655 | PRODUCT_NAME = "${TARGET_NAME}"; 656 | PROVISIONING_PROFILE = ""; 657 | SKIP_INSTALL = YES; 658 | }; 659 | name = Release; 660 | }; 661 | /* End XCBuildConfiguration section */ 662 | 663 | /* Begin XCConfigurationList section */ 664 | FA696A7A1A82921300E81513 /* Build configuration list for PBXProject "SharingWithFileCoordinator" */ = { 665 | isa = XCConfigurationList; 666 | buildConfigurations = ( 667 | FA696A9C1A82921300E81513 /* Debug */, 668 | FA696A9D1A82921300E81513 /* Release */, 669 | ); 670 | defaultConfigurationIsVisible = 0; 671 | defaultConfigurationName = Release; 672 | }; 673 | FA696A9E1A82921300E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinator" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | FA696A9F1A82921300E81513 /* Debug */, 677 | FA696AA01A82921300E81513 /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | }; 681 | FA696AA11A82921300E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinatorTests" */ = { 682 | isa = XCConfigurationList; 683 | buildConfigurations = ( 684 | FA696AA21A82921300E81513 /* Debug */, 685 | FA696AA31A82921300E81513 /* Release */, 686 | ); 687 | defaultConfigurationIsVisible = 0; 688 | }; 689 | FA696AC11A82BD5F00E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinator WatchKit App" */ = { 690 | isa = XCConfigurationList; 691 | buildConfigurations = ( 692 | FA696AC21A82BD5F00E81513 /* Debug */, 693 | FA696AC31A82BD5F00E81513 /* Release */, 694 | ); 695 | defaultConfigurationIsVisible = 0; 696 | }; 697 | FA696AC41A82BD5F00E81513 /* Build configuration list for PBXNativeTarget "SharingWithFileCoordinator WatchKit Extension" */ = { 698 | isa = XCConfigurationList; 699 | buildConfigurations = ( 700 | FA696AC51A82BD5F00E81513 /* Debug */, 701 | FA696AC61A82BD5F00E81513 /* Release */, 702 | ); 703 | defaultConfigurationIsVisible = 0; 704 | }; 705 | /* End XCConfigurationList section */ 706 | }; 707 | rootObject = FA696A771A82921300E81513 /* Project object */; 708 | } 709 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SharingWithFileCoordinator 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // 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. 24 | // 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. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 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 | func applicationDidBecomeActive(application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/Base.lproj/Main.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 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/InputTableViewCell.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InputTableViewCell.swift 3 | // SharingWithFileCoordinator 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class InputTableViewCell: UITableViewCell, UITextFieldDelegate { 12 | 13 | @IBOutlet weak private var taskTextField: UITextField! 14 | 15 | typealias onDoneHandlerType = (String?) -> Void 16 | private var onDoneHandler: onDoneHandlerType? 17 | 18 | override func awakeFromNib() { 19 | super.awakeFromNib() 20 | 21 | taskTextField.delegate = self 22 | } 23 | 24 | func configure(#onDoneHandler: onDoneHandlerType?) { 25 | self.onDoneHandler = onDoneHandler 26 | } 27 | 28 | // MARK: UITextFieldDelegate 29 | 30 | func textFieldShouldReturn(textField: UITextField) -> Bool { 31 | 32 | if let onDoneHandler = onDoneHandler { 33 | onDoneHandler(textField.text) 34 | textField.text = nil 35 | } 36 | 37 | return true 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/SharingWithFileCoordinator.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.natashatherobot.watchlist 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinator/TodoListTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // TodoListTableViewController.swift 3 | // SharingWithFileCoordinator 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class TodoListTableViewController: UITableViewController { 12 | 13 | var todoItems = [String]() 14 | var fileCoordinator = NSFileCoordinator() 15 | 16 | private let inputCellIdentifier = "inputCell" 17 | private let todoItemCellIdentifier = "todoItemCell" 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | fetchTodoItems() 23 | } 24 | 25 | // MARK: File Coordinator Operations 26 | 27 | private func fetchTodoItems() { 28 | 29 | // get the todo items array 30 | if let presentedItemURL = presentedItemURL { 31 | fileCoordinator.coordinateReadingItemAtURL(presentedItemURL, options: nil, error: nil) 32 | { [unowned self] (newURL) -> Void in 33 | 34 | if let savedData = NSData(contentsOfURL: newURL) { 35 | self.todoItems = NSKeyedUnarchiver.unarchiveObjectWithData(savedData) as [String] 36 | } 37 | } 38 | 39 | } 40 | } 41 | 42 | private func saveTodoItem(todoItem :String) { 43 | 44 | // write item into the todo items array 45 | if let presentedItemURL = presentedItemURL { 46 | 47 | fileCoordinator.coordinateWritingItemAtURL(presentedItemURL, options: nil, error: nil) 48 | { [unowned self] (newURL) -> Void in 49 | 50 | self.todoItems.insert(todoItem, atIndex: 0) 51 | 52 | let dataToSave = NSKeyedArchiver.archivedDataWithRootObject(self.todoItems) 53 | let success = dataToSave.writeToURL(newURL, atomically: true) 54 | } 55 | } 56 | } 57 | 58 | } 59 | 60 | // MARK: NSFilePresenter Protocol 61 | 62 | extension TodoListTableViewController: NSFilePresenter { 63 | 64 | var presentedItemURL: NSURL? { 65 | 66 | let groupURL = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier( 67 | "group.com.natashatherobot.watchlist") 68 | 69 | let fileURL = groupURL?.URLByAppendingPathComponent("todoItems.bin") 70 | return fileURL 71 | } 72 | 73 | var presentedItemOperationQueue: NSOperationQueue { 74 | return NSOperationQueue.mainQueue() 75 | } 76 | 77 | } 78 | 79 | // MARK: TableView Data Source 80 | 81 | extension TodoListTableViewController { 82 | 83 | override func numberOfSectionsInTableView(tableView: UITableView) -> Int { 84 | return 1 85 | } 86 | 87 | override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 88 | return todoItems.count + 1 89 | } 90 | 91 | override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 92 | var cell: UITableViewCell? 93 | if indexPath.row == 0 { 94 | cell = inputCell 95 | } else { 96 | let todoItemCell = tableView.dequeueReusableCellWithIdentifier(todoItemCellIdentifier) as UITableViewCell 97 | todoItemCell.textLabel?.text = self.todoItems[indexPath.row - 1] 98 | cell = todoItemCell 99 | } 100 | 101 | return cell ?? UITableViewCell() 102 | } 103 | 104 | } 105 | 106 | // MARK: Private Helper Functions 107 | 108 | private extension TodoListTableViewController { 109 | 110 | var inputCell: InputTableViewCell { 111 | let cell = tableView.dequeueReusableCellWithIdentifier(inputCellIdentifier) as InputTableViewCell 112 | cell.configure(onDoneHandler: { [unowned self] (inputText) -> Void in 113 | if let inputText = inputText { 114 | self.saveTodoItem(inputText) 115 | self.tableView.reloadData() 116 | } 117 | }) 118 | return cell 119 | } 120 | 121 | } 122 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinatorTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SharingWithFileCoordinator/SharingWithFileCoordinatorTests/SharingWithFileCoordinatorTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SharingWithFileCoordinatorTests.swift 3 | // SharingWithFileCoordinatorTests 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class SharingWithFileCoordinatorTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SharingWithFramework/MySharedDataLayer/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /SharingWithFramework/MySharedDataLayer/MySharedData.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MySharedData.swift 3 | // SharingWithFramework 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | public class MySharedData { 10 | 11 | public let myFavoriteThings = ["kittens", "ice cream", "travel"] 12 | 13 | public init() { 14 | 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /SharingWithFramework/MySharedDataLayerTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SharingWithFramework/MySharedDataLayerTests/MySharedDataLayerTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MySharedDataLayerTests.swift 3 | // MySharedDataLayerTests 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class MySharedDataLayerTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "appLauncher", 41 | "subtype" : "42mm" 42 | }, 43 | { 44 | "size" : "86x86", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "38mm" 49 | }, 50 | { 51 | "size" : "98x98", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "42mm" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework WatchKit App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingWithFramework 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingWithFramework.watchkitapp 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 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | com.natashatherobot.SharingWithFramework 32 | WKWatchKitApp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework WatchKit Extension/Images.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework WatchKit Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingWithFramework WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingWithFramework.watchkitextension 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | com.natashatherobot.SharingWithFramework.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | $(PRODUCT_MODULE_NAME).InterfaceController 37 | 38 | 39 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework WatchKit Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.swift 3 | // SharingWithFramework WatchKit Extension 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | import MySharedDataLayer 11 | 12 | class InterfaceController: WKInterfaceController { 13 | 14 | @IBOutlet weak var favoriteThingsLabel: WKInterfaceLabel! 15 | 16 | override func awakeWithContext(context: AnyObject?) { 17 | super.awakeWithContext(context) 18 | 19 | let myFavoriteThings = MySharedData().myFavoriteThings 20 | 21 | let favoriteThingsString = ", ".join(myFavoriteThings) 22 | favoriteThingsLabel.setText("My favorite things are \(favoriteThingsString)") 23 | } 24 | 25 | } 26 | 27 | 28 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SharingWithFramework 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // 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. 24 | // 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. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 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 | func applicationDidBecomeActive(application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFramework/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SharingWithFramework 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MySharedDataLayer 11 | 12 | class ViewController: UIViewController { 13 | 14 | @IBOutlet weak var favoriteThingsLabel: UILabel! 15 | 16 | override func viewDidLoad() { 17 | super.viewDidLoad() 18 | 19 | let myFavoriteThings = MySharedData().myFavoriteThings 20 | 21 | let favoriteThingsString = ", ".join(myFavoriteThings) 22 | favoriteThingsLabel.text = "My favorite things are \(favoriteThingsString)" 23 | } 24 | } 25 | 26 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFrameworkTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SharingWithFramework/SharingWithFrameworkTests/SharingWithFrameworkTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SharingWithFrameworkTests.swift 3 | // SharingWithFrameworkTests 4 | // 5 | // Created by Natasha Murashev on 2/5/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class SharingWithFrameworkTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit App/Base.lproj/Interface.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit App/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "24x24", 5 | "idiom" : "watch", 6 | "scale" : "2x", 7 | "role" : "notificationCenter", 8 | "subtype" : "38mm" 9 | }, 10 | { 11 | "size" : "27.5x27.5", 12 | "idiom" : "watch", 13 | "scale" : "2x", 14 | "role" : "notificationCenter", 15 | "subtype" : "42mm" 16 | }, 17 | { 18 | "size" : "29x29", 19 | "idiom" : "watch", 20 | "role" : "companionSettings", 21 | "scale" : "2x" 22 | }, 23 | { 24 | "size" : "29x29", 25 | "idiom" : "watch", 26 | "role" : "companionSettings", 27 | "scale" : "3x" 28 | }, 29 | { 30 | "size" : "40x40", 31 | "idiom" : "watch", 32 | "scale" : "2x", 33 | "role" : "appLauncher", 34 | "subtype" : "38mm" 35 | }, 36 | { 37 | "size" : "44x44", 38 | "idiom" : "watch", 39 | "scale" : "2x", 40 | "role" : "appLauncher", 41 | "subtype" : "42mm" 42 | }, 43 | { 44 | "size" : "86x86", 45 | "idiom" : "watch", 46 | "scale" : "2x", 47 | "role" : "quickLook", 48 | "subtype" : "38mm" 49 | }, 50 | { 51 | "size" : "98x98", 52 | "idiom" : "watch", 53 | "scale" : "2x", 54 | "role" : "quickLook", 55 | "subtype" : "42mm" 56 | } 57 | ], 58 | "info" : { 59 | "version" : 1, 60 | "author" : "xcode" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit App/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingWithUserDefaults 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingWithUserDefaults.watchkitapp 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 25 | UISupportedInterfaceOrientations 26 | 27 | UIInterfaceOrientationPortrait 28 | UIInterfaceOrientationPortraitUpsideDown 29 | 30 | WKCompanionAppBundleIdentifier 31 | com.natashatherobot.SharingWithUserDefaults 32 | WKWatchKitApp 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit Extension/Images.xcassets/README__ignoredByTemplate__: -------------------------------------------------------------------------------- 1 | Did you know that git does not support storing empty directories? 2 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit Extension/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | SharingWithUserDefaults WatchKit Extension 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | com.natashatherobot.SharingWithUserDefaults.watchkitextension 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | XPC! 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | NSExtension 26 | 27 | NSExtensionAttributes 28 | 29 | WKAppBundleIdentifier 30 | com.natashatherobot.SharingWithUserDefaults.watchkitapp 31 | 32 | NSExtensionPointIdentifier 33 | com.apple.watchkit 34 | 35 | RemoteInterfacePrincipalClass 36 | $(PRODUCT_MODULE_NAME).InterfaceController 37 | 38 | 39 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit Extension/InterfaceController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InterfaceController.swift 3 | // SharingWithUserDefaults WatchKit Extension 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import WatchKit 10 | 11 | class InterfaceController: WKInterfaceController { 12 | 13 | @IBOutlet weak var textLabel: WKInterfaceLabel! 14 | 15 | let defaults = NSUserDefaults(suiteName: 16 | "group.com.natashatherobot.userdefaults") 17 | 18 | var userInput: String? { 19 | defaults?.synchronize() 20 | return defaults?.stringForKey("userInput") 21 | } 22 | 23 | override func awakeWithContext(context: AnyObject?) { 24 | super.awakeWithContext(context) 25 | 26 | textLabel.setText(userInput) 27 | } 28 | 29 | // MARK: IBActions 30 | 31 | @IBAction func onUpdateTap() { 32 | textLabel.setText(userInput) 33 | } 34 | 35 | } 36 | 37 | 38 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults WatchKit Extension/SharingWithUserDefaults WatchKit Extension.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.natashatherobot.userdefaults 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | FA696A311A823D0E00E81513 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696A301A823D0E00E81513 /* AppDelegate.swift */; }; 11 | FA696A331A823D0E00E81513 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696A321A823D0E00E81513 /* ViewController.swift */; }; 12 | FA696A361A823D0E00E81513 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA696A341A823D0E00E81513 /* Main.storyboard */; }; 13 | FA696A381A823D0E00E81513 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA696A371A823D0E00E81513 /* Images.xcassets */; }; 14 | FA696A3B1A823D0E00E81513 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = FA696A391A823D0E00E81513 /* LaunchScreen.xib */; }; 15 | FA696A471A823D0E00E81513 /* SharingWithUserDefaultsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696A461A823D0E00E81513 /* SharingWithUserDefaultsTests.swift */; }; 16 | FA696A5A1A82436200E81513 /* InterfaceController.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA696A591A82436200E81513 /* InterfaceController.swift */; }; 17 | FA696A5C1A82436200E81513 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA696A5B1A82436200E81513 /* Images.xcassets */; }; 18 | FA696A601A82436200E81513 /* SharingWithUserDefaults WatchKit App.app in Resources */ = {isa = PBXBuildFile; fileRef = FA696A5F1A82436200E81513 /* SharingWithUserDefaults WatchKit App.app */; }; 19 | FA696A681A82436200E81513 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = FA696A661A82436200E81513 /* Interface.storyboard */; }; 20 | FA696A6A1A82436200E81513 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = FA696A691A82436200E81513 /* Images.xcassets */; }; 21 | FA696A6D1A82436200E81513 /* SharingWithUserDefaults WatchKit Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = FA696A551A82436200E81513 /* SharingWithUserDefaults WatchKit Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; 22 | /* End PBXBuildFile section */ 23 | 24 | /* Begin PBXContainerItemProxy section */ 25 | FA696A411A823D0E00E81513 /* PBXContainerItemProxy */ = { 26 | isa = PBXContainerItemProxy; 27 | containerPortal = FA696A231A823D0D00E81513 /* Project object */; 28 | proxyType = 1; 29 | remoteGlobalIDString = FA696A2A1A823D0D00E81513; 30 | remoteInfo = SharingWithUserDefaults; 31 | }; 32 | FA696A611A82436200E81513 /* PBXContainerItemProxy */ = { 33 | isa = PBXContainerItemProxy; 34 | containerPortal = FA696A231A823D0D00E81513 /* Project object */; 35 | proxyType = 1; 36 | remoteGlobalIDString = FA696A5E1A82436200E81513; 37 | remoteInfo = "SharingWithUserDefaults WatchKit App"; 38 | }; 39 | FA696A6B1A82436200E81513 /* PBXContainerItemProxy */ = { 40 | isa = PBXContainerItemProxy; 41 | containerPortal = FA696A231A823D0D00E81513 /* Project object */; 42 | proxyType = 1; 43 | remoteGlobalIDString = FA696A541A82436200E81513; 44 | remoteInfo = "SharingWithUserDefaults WatchKit Extension"; 45 | }; 46 | /* End PBXContainerItemProxy section */ 47 | 48 | /* Begin PBXCopyFilesBuildPhase section */ 49 | FA696A741A82436300E81513 /* Embed App Extensions */ = { 50 | isa = PBXCopyFilesBuildPhase; 51 | buildActionMask = 2147483647; 52 | dstPath = ""; 53 | dstSubfolderSpec = 13; 54 | files = ( 55 | FA696A6D1A82436200E81513 /* SharingWithUserDefaults WatchKit Extension.appex in Embed App Extensions */, 56 | ); 57 | name = "Embed App Extensions"; 58 | runOnlyForDeploymentPostprocessing = 0; 59 | }; 60 | /* End PBXCopyFilesBuildPhase section */ 61 | 62 | /* Begin PBXFileReference section */ 63 | FA696A2B1A823D0E00E81513 /* SharingWithUserDefaults.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SharingWithUserDefaults.app; sourceTree = BUILT_PRODUCTS_DIR; }; 64 | FA696A2F1A823D0E00E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 65 | FA696A301A823D0E00E81513 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 66 | FA696A321A823D0E00E81513 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 67 | FA696A351A823D0E00E81513 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 68 | FA696A371A823D0E00E81513 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 69 | FA696A3A1A823D0E00E81513 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 70 | FA696A401A823D0E00E81513 /* SharingWithUserDefaultsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = SharingWithUserDefaultsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 71 | FA696A451A823D0E00E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 72 | FA696A461A823D0E00E81513 /* SharingWithUserDefaultsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SharingWithUserDefaultsTests.swift; sourceTree = ""; }; 73 | FA696A501A82433200E81513 /* SharingWithUserDefaults.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = SharingWithUserDefaults.entitlements; sourceTree = ""; }; 74 | FA696A551A82436200E81513 /* SharingWithUserDefaults WatchKit Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "SharingWithUserDefaults WatchKit Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; 75 | FA696A581A82436200E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 76 | FA696A591A82436200E81513 /* InterfaceController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InterfaceController.swift; sourceTree = ""; }; 77 | FA696A5B1A82436200E81513 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 78 | FA696A5F1A82436200E81513 /* SharingWithUserDefaults WatchKit App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SharingWithUserDefaults WatchKit App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; 79 | FA696A651A82436200E81513 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 80 | FA696A671A82436200E81513 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; 81 | FA696A691A82436200E81513 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 82 | FA696A751A82436F00E81513 /* SharingWithUserDefaults WatchKit Extension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "SharingWithUserDefaults WatchKit Extension.entitlements"; sourceTree = ""; }; 83 | /* End PBXFileReference section */ 84 | 85 | /* Begin PBXFrameworksBuildPhase section */ 86 | FA696A281A823D0D00E81513 /* Frameworks */ = { 87 | isa = PBXFrameworksBuildPhase; 88 | buildActionMask = 2147483647; 89 | files = ( 90 | ); 91 | runOnlyForDeploymentPostprocessing = 0; 92 | }; 93 | FA696A3D1A823D0E00E81513 /* Frameworks */ = { 94 | isa = PBXFrameworksBuildPhase; 95 | buildActionMask = 2147483647; 96 | files = ( 97 | ); 98 | runOnlyForDeploymentPostprocessing = 0; 99 | }; 100 | FA696A521A82436200E81513 /* Frameworks */ = { 101 | isa = PBXFrameworksBuildPhase; 102 | buildActionMask = 2147483647; 103 | files = ( 104 | ); 105 | runOnlyForDeploymentPostprocessing = 0; 106 | }; 107 | /* End PBXFrameworksBuildPhase section */ 108 | 109 | /* Begin PBXGroup section */ 110 | FA696A221A823D0D00E81513 = { 111 | isa = PBXGroup; 112 | children = ( 113 | FA696A2D1A823D0E00E81513 /* SharingWithUserDefaults */, 114 | FA696A431A823D0E00E81513 /* SharingWithUserDefaultsTests */, 115 | FA696A561A82436200E81513 /* SharingWithUserDefaults WatchKit Extension */, 116 | FA696A631A82436200E81513 /* SharingWithUserDefaults WatchKit App */, 117 | FA696A2C1A823D0E00E81513 /* Products */, 118 | ); 119 | sourceTree = ""; 120 | }; 121 | FA696A2C1A823D0E00E81513 /* Products */ = { 122 | isa = PBXGroup; 123 | children = ( 124 | FA696A2B1A823D0E00E81513 /* SharingWithUserDefaults.app */, 125 | FA696A401A823D0E00E81513 /* SharingWithUserDefaultsTests.xctest */, 126 | FA696A551A82436200E81513 /* SharingWithUserDefaults WatchKit Extension.appex */, 127 | FA696A5F1A82436200E81513 /* SharingWithUserDefaults WatchKit App.app */, 128 | ); 129 | name = Products; 130 | sourceTree = ""; 131 | }; 132 | FA696A2D1A823D0E00E81513 /* SharingWithUserDefaults */ = { 133 | isa = PBXGroup; 134 | children = ( 135 | FA696A501A82433200E81513 /* SharingWithUserDefaults.entitlements */, 136 | FA696A301A823D0E00E81513 /* AppDelegate.swift */, 137 | FA696A321A823D0E00E81513 /* ViewController.swift */, 138 | FA696A341A823D0E00E81513 /* Main.storyboard */, 139 | FA696A371A823D0E00E81513 /* Images.xcassets */, 140 | FA696A391A823D0E00E81513 /* LaunchScreen.xib */, 141 | FA696A2E1A823D0E00E81513 /* Supporting Files */, 142 | ); 143 | path = SharingWithUserDefaults; 144 | sourceTree = ""; 145 | }; 146 | FA696A2E1A823D0E00E81513 /* Supporting Files */ = { 147 | isa = PBXGroup; 148 | children = ( 149 | FA696A2F1A823D0E00E81513 /* Info.plist */, 150 | ); 151 | name = "Supporting Files"; 152 | sourceTree = ""; 153 | }; 154 | FA696A431A823D0E00E81513 /* SharingWithUserDefaultsTests */ = { 155 | isa = PBXGroup; 156 | children = ( 157 | FA696A461A823D0E00E81513 /* SharingWithUserDefaultsTests.swift */, 158 | FA696A441A823D0E00E81513 /* Supporting Files */, 159 | ); 160 | path = SharingWithUserDefaultsTests; 161 | sourceTree = ""; 162 | }; 163 | FA696A441A823D0E00E81513 /* Supporting Files */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | FA696A451A823D0E00E81513 /* Info.plist */, 167 | ); 168 | name = "Supporting Files"; 169 | sourceTree = ""; 170 | }; 171 | FA696A561A82436200E81513 /* SharingWithUserDefaults WatchKit Extension */ = { 172 | isa = PBXGroup; 173 | children = ( 174 | FA696A751A82436F00E81513 /* SharingWithUserDefaults WatchKit Extension.entitlements */, 175 | FA696A591A82436200E81513 /* InterfaceController.swift */, 176 | FA696A5B1A82436200E81513 /* Images.xcassets */, 177 | FA696A571A82436200E81513 /* Supporting Files */, 178 | ); 179 | path = "SharingWithUserDefaults WatchKit Extension"; 180 | sourceTree = ""; 181 | }; 182 | FA696A571A82436200E81513 /* Supporting Files */ = { 183 | isa = PBXGroup; 184 | children = ( 185 | FA696A581A82436200E81513 /* Info.plist */, 186 | ); 187 | name = "Supporting Files"; 188 | sourceTree = ""; 189 | }; 190 | FA696A631A82436200E81513 /* SharingWithUserDefaults WatchKit App */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | FA696A661A82436200E81513 /* Interface.storyboard */, 194 | FA696A691A82436200E81513 /* Images.xcassets */, 195 | FA696A641A82436200E81513 /* Supporting Files */, 196 | ); 197 | path = "SharingWithUserDefaults WatchKit App"; 198 | sourceTree = ""; 199 | }; 200 | FA696A641A82436200E81513 /* Supporting Files */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | FA696A651A82436200E81513 /* Info.plist */, 204 | ); 205 | name = "Supporting Files"; 206 | sourceTree = ""; 207 | }; 208 | /* End PBXGroup section */ 209 | 210 | /* Begin PBXNativeTarget section */ 211 | FA696A2A1A823D0D00E81513 /* SharingWithUserDefaults */ = { 212 | isa = PBXNativeTarget; 213 | buildConfigurationList = FA696A4A1A823D0E00E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaults" */; 214 | buildPhases = ( 215 | FA696A271A823D0D00E81513 /* Sources */, 216 | FA696A281A823D0D00E81513 /* Frameworks */, 217 | FA696A291A823D0D00E81513 /* Resources */, 218 | FA696A741A82436300E81513 /* Embed App Extensions */, 219 | ); 220 | buildRules = ( 221 | ); 222 | dependencies = ( 223 | FA696A6C1A82436200E81513 /* PBXTargetDependency */, 224 | ); 225 | name = SharingWithUserDefaults; 226 | productName = SharingWithUserDefaults; 227 | productReference = FA696A2B1A823D0E00E81513 /* SharingWithUserDefaults.app */; 228 | productType = "com.apple.product-type.application"; 229 | }; 230 | FA696A3F1A823D0E00E81513 /* SharingWithUserDefaultsTests */ = { 231 | isa = PBXNativeTarget; 232 | buildConfigurationList = FA696A4D1A823D0E00E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaultsTests" */; 233 | buildPhases = ( 234 | FA696A3C1A823D0E00E81513 /* Sources */, 235 | FA696A3D1A823D0E00E81513 /* Frameworks */, 236 | FA696A3E1A823D0E00E81513 /* Resources */, 237 | ); 238 | buildRules = ( 239 | ); 240 | dependencies = ( 241 | FA696A421A823D0E00E81513 /* PBXTargetDependency */, 242 | ); 243 | name = SharingWithUserDefaultsTests; 244 | productName = SharingWithUserDefaultsTests; 245 | productReference = FA696A401A823D0E00E81513 /* SharingWithUserDefaultsTests.xctest */; 246 | productType = "com.apple.product-type.bundle.unit-test"; 247 | }; 248 | FA696A541A82436200E81513 /* SharingWithUserDefaults WatchKit Extension */ = { 249 | isa = PBXNativeTarget; 250 | buildConfigurationList = FA696A711A82436300E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaults WatchKit Extension" */; 251 | buildPhases = ( 252 | FA696A511A82436200E81513 /* Sources */, 253 | FA696A521A82436200E81513 /* Frameworks */, 254 | FA696A531A82436200E81513 /* Resources */, 255 | ); 256 | buildRules = ( 257 | ); 258 | dependencies = ( 259 | FA696A621A82436200E81513 /* PBXTargetDependency */, 260 | ); 261 | name = "SharingWithUserDefaults WatchKit Extension"; 262 | productName = "SharingWithUserDefaults WatchKit Extension"; 263 | productReference = FA696A551A82436200E81513 /* SharingWithUserDefaults WatchKit Extension.appex */; 264 | productType = "com.apple.product-type.watchkit-extension"; 265 | }; 266 | FA696A5E1A82436200E81513 /* SharingWithUserDefaults WatchKit App */ = { 267 | isa = PBXNativeTarget; 268 | buildConfigurationList = FA696A6E1A82436300E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaults WatchKit App" */; 269 | buildPhases = ( 270 | FA696A5D1A82436200E81513 /* Resources */, 271 | ); 272 | buildRules = ( 273 | ); 274 | dependencies = ( 275 | ); 276 | name = "SharingWithUserDefaults WatchKit App"; 277 | productName = "SharingWithUserDefaults WatchKit App"; 278 | productReference = FA696A5F1A82436200E81513 /* SharingWithUserDefaults WatchKit App.app */; 279 | productType = "com.apple.product-type.application.watchapp"; 280 | }; 281 | /* End PBXNativeTarget section */ 282 | 283 | /* Begin PBXProject section */ 284 | FA696A231A823D0D00E81513 /* Project object */ = { 285 | isa = PBXProject; 286 | attributes = { 287 | LastUpgradeCheck = 0620; 288 | ORGANIZATIONNAME = NatashaTheRobot; 289 | TargetAttributes = { 290 | FA696A2A1A823D0D00E81513 = { 291 | CreatedOnToolsVersion = 6.2; 292 | DevelopmentTeam = W6GNU64U6Q; 293 | SystemCapabilities = { 294 | com.apple.ApplicationGroups.iOS = { 295 | enabled = 1; 296 | }; 297 | }; 298 | }; 299 | FA696A3F1A823D0E00E81513 = { 300 | CreatedOnToolsVersion = 6.2; 301 | TestTargetID = FA696A2A1A823D0D00E81513; 302 | }; 303 | FA696A541A82436200E81513 = { 304 | CreatedOnToolsVersion = 6.2; 305 | DevelopmentTeam = W6GNU64U6Q; 306 | SystemCapabilities = { 307 | com.apple.ApplicationGroups.iOS = { 308 | enabled = 1; 309 | }; 310 | }; 311 | }; 312 | FA696A5E1A82436200E81513 = { 313 | CreatedOnToolsVersion = 6.2; 314 | }; 315 | }; 316 | }; 317 | buildConfigurationList = FA696A261A823D0D00E81513 /* Build configuration list for PBXProject "SharingWithUserDefaults" */; 318 | compatibilityVersion = "Xcode 3.2"; 319 | developmentRegion = English; 320 | hasScannedForEncodings = 0; 321 | knownRegions = ( 322 | en, 323 | Base, 324 | ); 325 | mainGroup = FA696A221A823D0D00E81513; 326 | productRefGroup = FA696A2C1A823D0E00E81513 /* Products */; 327 | projectDirPath = ""; 328 | projectRoot = ""; 329 | targets = ( 330 | FA696A2A1A823D0D00E81513 /* SharingWithUserDefaults */, 331 | FA696A3F1A823D0E00E81513 /* SharingWithUserDefaultsTests */, 332 | FA696A541A82436200E81513 /* SharingWithUserDefaults WatchKit Extension */, 333 | FA696A5E1A82436200E81513 /* SharingWithUserDefaults WatchKit App */, 334 | ); 335 | }; 336 | /* End PBXProject section */ 337 | 338 | /* Begin PBXResourcesBuildPhase section */ 339 | FA696A291A823D0D00E81513 /* Resources */ = { 340 | isa = PBXResourcesBuildPhase; 341 | buildActionMask = 2147483647; 342 | files = ( 343 | FA696A361A823D0E00E81513 /* Main.storyboard in Resources */, 344 | FA696A3B1A823D0E00E81513 /* LaunchScreen.xib in Resources */, 345 | FA696A381A823D0E00E81513 /* Images.xcassets in Resources */, 346 | ); 347 | runOnlyForDeploymentPostprocessing = 0; 348 | }; 349 | FA696A3E1A823D0E00E81513 /* Resources */ = { 350 | isa = PBXResourcesBuildPhase; 351 | buildActionMask = 2147483647; 352 | files = ( 353 | ); 354 | runOnlyForDeploymentPostprocessing = 0; 355 | }; 356 | FA696A531A82436200E81513 /* Resources */ = { 357 | isa = PBXResourcesBuildPhase; 358 | buildActionMask = 2147483647; 359 | files = ( 360 | FA696A601A82436200E81513 /* SharingWithUserDefaults WatchKit App.app in Resources */, 361 | FA696A5C1A82436200E81513 /* Images.xcassets in Resources */, 362 | ); 363 | runOnlyForDeploymentPostprocessing = 0; 364 | }; 365 | FA696A5D1A82436200E81513 /* Resources */ = { 366 | isa = PBXResourcesBuildPhase; 367 | buildActionMask = 2147483647; 368 | files = ( 369 | FA696A681A82436200E81513 /* Interface.storyboard in Resources */, 370 | FA696A6A1A82436200E81513 /* Images.xcassets in Resources */, 371 | ); 372 | runOnlyForDeploymentPostprocessing = 0; 373 | }; 374 | /* End PBXResourcesBuildPhase section */ 375 | 376 | /* Begin PBXSourcesBuildPhase section */ 377 | FA696A271A823D0D00E81513 /* Sources */ = { 378 | isa = PBXSourcesBuildPhase; 379 | buildActionMask = 2147483647; 380 | files = ( 381 | FA696A331A823D0E00E81513 /* ViewController.swift in Sources */, 382 | FA696A311A823D0E00E81513 /* AppDelegate.swift in Sources */, 383 | ); 384 | runOnlyForDeploymentPostprocessing = 0; 385 | }; 386 | FA696A3C1A823D0E00E81513 /* Sources */ = { 387 | isa = PBXSourcesBuildPhase; 388 | buildActionMask = 2147483647; 389 | files = ( 390 | FA696A471A823D0E00E81513 /* SharingWithUserDefaultsTests.swift in Sources */, 391 | ); 392 | runOnlyForDeploymentPostprocessing = 0; 393 | }; 394 | FA696A511A82436200E81513 /* Sources */ = { 395 | isa = PBXSourcesBuildPhase; 396 | buildActionMask = 2147483647; 397 | files = ( 398 | FA696A5A1A82436200E81513 /* InterfaceController.swift in Sources */, 399 | ); 400 | runOnlyForDeploymentPostprocessing = 0; 401 | }; 402 | /* End PBXSourcesBuildPhase section */ 403 | 404 | /* Begin PBXTargetDependency section */ 405 | FA696A421A823D0E00E81513 /* PBXTargetDependency */ = { 406 | isa = PBXTargetDependency; 407 | target = FA696A2A1A823D0D00E81513 /* SharingWithUserDefaults */; 408 | targetProxy = FA696A411A823D0E00E81513 /* PBXContainerItemProxy */; 409 | }; 410 | FA696A621A82436200E81513 /* PBXTargetDependency */ = { 411 | isa = PBXTargetDependency; 412 | target = FA696A5E1A82436200E81513 /* SharingWithUserDefaults WatchKit App */; 413 | targetProxy = FA696A611A82436200E81513 /* PBXContainerItemProxy */; 414 | }; 415 | FA696A6C1A82436200E81513 /* PBXTargetDependency */ = { 416 | isa = PBXTargetDependency; 417 | target = FA696A541A82436200E81513 /* SharingWithUserDefaults WatchKit Extension */; 418 | targetProxy = FA696A6B1A82436200E81513 /* PBXContainerItemProxy */; 419 | }; 420 | /* End PBXTargetDependency section */ 421 | 422 | /* Begin PBXVariantGroup section */ 423 | FA696A341A823D0E00E81513 /* Main.storyboard */ = { 424 | isa = PBXVariantGroup; 425 | children = ( 426 | FA696A351A823D0E00E81513 /* Base */, 427 | ); 428 | name = Main.storyboard; 429 | sourceTree = ""; 430 | }; 431 | FA696A391A823D0E00E81513 /* LaunchScreen.xib */ = { 432 | isa = PBXVariantGroup; 433 | children = ( 434 | FA696A3A1A823D0E00E81513 /* Base */, 435 | ); 436 | name = LaunchScreen.xib; 437 | sourceTree = ""; 438 | }; 439 | FA696A661A82436200E81513 /* Interface.storyboard */ = { 440 | isa = PBXVariantGroup; 441 | children = ( 442 | FA696A671A82436200E81513 /* Base */, 443 | ); 444 | name = Interface.storyboard; 445 | sourceTree = ""; 446 | }; 447 | /* End PBXVariantGroup section */ 448 | 449 | /* Begin XCBuildConfiguration section */ 450 | FA696A481A823D0E00E81513 /* Debug */ = { 451 | isa = XCBuildConfiguration; 452 | buildSettings = { 453 | ALWAYS_SEARCH_USER_PATHS = NO; 454 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 455 | CLANG_CXX_LIBRARY = "libc++"; 456 | CLANG_ENABLE_MODULES = YES; 457 | CLANG_ENABLE_OBJC_ARC = YES; 458 | CLANG_WARN_BOOL_CONVERSION = YES; 459 | CLANG_WARN_CONSTANT_CONVERSION = YES; 460 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 461 | CLANG_WARN_EMPTY_BODY = YES; 462 | CLANG_WARN_ENUM_CONVERSION = YES; 463 | CLANG_WARN_INT_CONVERSION = YES; 464 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 465 | CLANG_WARN_UNREACHABLE_CODE = YES; 466 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 467 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 468 | COPY_PHASE_STRIP = NO; 469 | ENABLE_STRICT_OBJC_MSGSEND = YES; 470 | GCC_C_LANGUAGE_STANDARD = gnu99; 471 | GCC_DYNAMIC_NO_PIC = NO; 472 | GCC_OPTIMIZATION_LEVEL = 0; 473 | GCC_PREPROCESSOR_DEFINITIONS = ( 474 | "DEBUG=1", 475 | "$(inherited)", 476 | ); 477 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 478 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 479 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 480 | GCC_WARN_UNDECLARED_SELECTOR = YES; 481 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 482 | GCC_WARN_UNUSED_FUNCTION = YES; 483 | GCC_WARN_UNUSED_VARIABLE = YES; 484 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 485 | MTL_ENABLE_DEBUG_INFO = YES; 486 | ONLY_ACTIVE_ARCH = YES; 487 | SDKROOT = iphoneos; 488 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 489 | }; 490 | name = Debug; 491 | }; 492 | FA696A491A823D0E00E81513 /* Release */ = { 493 | isa = XCBuildConfiguration; 494 | buildSettings = { 495 | ALWAYS_SEARCH_USER_PATHS = NO; 496 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 497 | CLANG_CXX_LIBRARY = "libc++"; 498 | CLANG_ENABLE_MODULES = YES; 499 | CLANG_ENABLE_OBJC_ARC = YES; 500 | CLANG_WARN_BOOL_CONVERSION = YES; 501 | CLANG_WARN_CONSTANT_CONVERSION = YES; 502 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 503 | CLANG_WARN_EMPTY_BODY = YES; 504 | CLANG_WARN_ENUM_CONVERSION = YES; 505 | CLANG_WARN_INT_CONVERSION = YES; 506 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 507 | CLANG_WARN_UNREACHABLE_CODE = YES; 508 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 509 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 510 | COPY_PHASE_STRIP = NO; 511 | ENABLE_NS_ASSERTIONS = NO; 512 | ENABLE_STRICT_OBJC_MSGSEND = YES; 513 | GCC_C_LANGUAGE_STANDARD = gnu99; 514 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 515 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 516 | GCC_WARN_UNDECLARED_SELECTOR = YES; 517 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 518 | GCC_WARN_UNUSED_FUNCTION = YES; 519 | GCC_WARN_UNUSED_VARIABLE = YES; 520 | IPHONEOS_DEPLOYMENT_TARGET = 8.2; 521 | MTL_ENABLE_DEBUG_INFO = NO; 522 | SDKROOT = iphoneos; 523 | VALIDATE_PRODUCT = YES; 524 | }; 525 | name = Release; 526 | }; 527 | FA696A4B1A823D0E00E81513 /* Debug */ = { 528 | isa = XCBuildConfiguration; 529 | buildSettings = { 530 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 531 | CODE_SIGN_ENTITLEMENTS = SharingWithUserDefaults/SharingWithUserDefaults.entitlements; 532 | CODE_SIGN_IDENTITY = "iPhone Developer"; 533 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 534 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 535 | INFOPLIST_FILE = SharingWithUserDefaults/Info.plist; 536 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 537 | PRODUCT_NAME = "$(TARGET_NAME)"; 538 | PROVISIONING_PROFILE = ""; 539 | }; 540 | name = Debug; 541 | }; 542 | FA696A4C1A823D0E00E81513 /* Release */ = { 543 | isa = XCBuildConfiguration; 544 | buildSettings = { 545 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 546 | CODE_SIGN_ENTITLEMENTS = SharingWithUserDefaults/SharingWithUserDefaults.entitlements; 547 | CODE_SIGN_IDENTITY = "iPhone Developer"; 548 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 549 | EMBEDDED_CONTENT_CONTAINS_SWIFT = YES; 550 | INFOPLIST_FILE = SharingWithUserDefaults/Info.plist; 551 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 552 | PRODUCT_NAME = "$(TARGET_NAME)"; 553 | PROVISIONING_PROFILE = ""; 554 | }; 555 | name = Release; 556 | }; 557 | FA696A4E1A823D0E00E81513 /* Debug */ = { 558 | isa = XCBuildConfiguration; 559 | buildSettings = { 560 | BUNDLE_LOADER = "$(TEST_HOST)"; 561 | FRAMEWORK_SEARCH_PATHS = ( 562 | "$(SDKROOT)/Developer/Library/Frameworks", 563 | "$(inherited)", 564 | ); 565 | GCC_PREPROCESSOR_DEFINITIONS = ( 566 | "DEBUG=1", 567 | "$(inherited)", 568 | ); 569 | INFOPLIST_FILE = SharingWithUserDefaultsTests/Info.plist; 570 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 571 | PRODUCT_NAME = "$(TARGET_NAME)"; 572 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SharingWithUserDefaults.app/SharingWithUserDefaults"; 573 | }; 574 | name = Debug; 575 | }; 576 | FA696A4F1A823D0E00E81513 /* Release */ = { 577 | isa = XCBuildConfiguration; 578 | buildSettings = { 579 | BUNDLE_LOADER = "$(TEST_HOST)"; 580 | FRAMEWORK_SEARCH_PATHS = ( 581 | "$(SDKROOT)/Developer/Library/Frameworks", 582 | "$(inherited)", 583 | ); 584 | INFOPLIST_FILE = SharingWithUserDefaultsTests/Info.plist; 585 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 586 | PRODUCT_NAME = "$(TARGET_NAME)"; 587 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/SharingWithUserDefaults.app/SharingWithUserDefaults"; 588 | }; 589 | name = Release; 590 | }; 591 | FA696A6F1A82436300E81513 /* Debug */ = { 592 | isa = XCBuildConfiguration; 593 | buildSettings = { 594 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 595 | GCC_PREPROCESSOR_DEFINITIONS = ( 596 | "DEBUG=1", 597 | "$(inherited)", 598 | ); 599 | IBSC_MODULE = SharingWithUserDefaults_WatchKit_Extension; 600 | INFOPLIST_FILE = "SharingWithUserDefaults WatchKit App/Info.plist"; 601 | PRODUCT_NAME = "$(TARGET_NAME)"; 602 | SKIP_INSTALL = YES; 603 | TARGETED_DEVICE_FAMILY = 4; 604 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4"; 605 | }; 606 | name = Debug; 607 | }; 608 | FA696A701A82436300E81513 /* Release */ = { 609 | isa = XCBuildConfiguration; 610 | buildSettings = { 611 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 612 | IBSC_MODULE = SharingWithUserDefaults_WatchKit_Extension; 613 | INFOPLIST_FILE = "SharingWithUserDefaults WatchKit App/Info.plist"; 614 | PRODUCT_NAME = "$(TARGET_NAME)"; 615 | SKIP_INSTALL = YES; 616 | TARGETED_DEVICE_FAMILY = 4; 617 | "TARGETED_DEVICE_FAMILY[sdk=iphonesimulator*]" = "1,4"; 618 | }; 619 | name = Release; 620 | }; 621 | FA696A721A82436300E81513 /* Debug */ = { 622 | isa = XCBuildConfiguration; 623 | buildSettings = { 624 | CODE_SIGN_ENTITLEMENTS = "SharingWithUserDefaults WatchKit Extension/SharingWithUserDefaults WatchKit Extension.entitlements"; 625 | CODE_SIGN_IDENTITY = "iPhone Developer"; 626 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 627 | GCC_PREPROCESSOR_DEFINITIONS = ( 628 | "DEBUG=1", 629 | "$(inherited)", 630 | ); 631 | INFOPLIST_FILE = "SharingWithUserDefaults WatchKit Extension/Info.plist"; 632 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 633 | PRODUCT_NAME = "${TARGET_NAME}"; 634 | PROVISIONING_PROFILE = ""; 635 | SKIP_INSTALL = YES; 636 | }; 637 | name = Debug; 638 | }; 639 | FA696A731A82436300E81513 /* Release */ = { 640 | isa = XCBuildConfiguration; 641 | buildSettings = { 642 | CODE_SIGN_ENTITLEMENTS = "SharingWithUserDefaults WatchKit Extension/SharingWithUserDefaults WatchKit Extension.entitlements"; 643 | CODE_SIGN_IDENTITY = "iPhone Developer"; 644 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 645 | INFOPLIST_FILE = "SharingWithUserDefaults WatchKit Extension/Info.plist"; 646 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; 647 | PRODUCT_NAME = "${TARGET_NAME}"; 648 | PROVISIONING_PROFILE = ""; 649 | SKIP_INSTALL = YES; 650 | }; 651 | name = Release; 652 | }; 653 | /* End XCBuildConfiguration section */ 654 | 655 | /* Begin XCConfigurationList section */ 656 | FA696A261A823D0D00E81513 /* Build configuration list for PBXProject "SharingWithUserDefaults" */ = { 657 | isa = XCConfigurationList; 658 | buildConfigurations = ( 659 | FA696A481A823D0E00E81513 /* Debug */, 660 | FA696A491A823D0E00E81513 /* Release */, 661 | ); 662 | defaultConfigurationIsVisible = 0; 663 | defaultConfigurationName = Release; 664 | }; 665 | FA696A4A1A823D0E00E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaults" */ = { 666 | isa = XCConfigurationList; 667 | buildConfigurations = ( 668 | FA696A4B1A823D0E00E81513 /* Debug */, 669 | FA696A4C1A823D0E00E81513 /* Release */, 670 | ); 671 | defaultConfigurationIsVisible = 0; 672 | }; 673 | FA696A4D1A823D0E00E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaultsTests" */ = { 674 | isa = XCConfigurationList; 675 | buildConfigurations = ( 676 | FA696A4E1A823D0E00E81513 /* Debug */, 677 | FA696A4F1A823D0E00E81513 /* Release */, 678 | ); 679 | defaultConfigurationIsVisible = 0; 680 | }; 681 | FA696A6E1A82436300E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaults WatchKit App" */ = { 682 | isa = XCConfigurationList; 683 | buildConfigurations = ( 684 | FA696A6F1A82436300E81513 /* Debug */, 685 | FA696A701A82436300E81513 /* Release */, 686 | ); 687 | defaultConfigurationIsVisible = 0; 688 | }; 689 | FA696A711A82436300E81513 /* Build configuration list for PBXNativeTarget "SharingWithUserDefaults WatchKit Extension" */ = { 690 | isa = XCConfigurationList; 691 | buildConfigurations = ( 692 | FA696A721A82436300E81513 /* Debug */, 693 | FA696A731A82436300E81513 /* Release */, 694 | ); 695 | defaultConfigurationIsVisible = 0; 696 | }; 697 | /* End XCConfigurationList section */ 698 | }; 699 | rootObject = FA696A231A823D0D00E81513 /* Project object */; 700 | } 701 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // SharingWithUserDefaults 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(application: UIApplication) { 23 | // 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. 24 | // 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. 25 | } 26 | 27 | func applicationDidEnterBackground(application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(application: UIApplication) { 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 | func applicationDidBecomeActive(application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/Base.lproj/LaunchScreen.xib: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 26 | 27 | 28 | 29 | 30 | 31 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/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" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | armv7 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/SharingWithUserDefaults.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | com.apple.security.application-groups 6 | 7 | group.com.natashatherobot.userdefaults 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaults/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // SharingWithUserDefaults 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | @IBOutlet weak var textLabel: UILabel! 14 | @IBOutlet weak var textField: UITextField! 15 | 16 | let defaults = NSUserDefaults(suiteName: "group.com.natashatherobot.userdefaults") 17 | let key = "userInput" 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | textLabel.text = defaults?.stringForKey(key) ?? "Type Something..." 23 | } 24 | 25 | 26 | @IBAction func onSaveTap(sender: AnyObject) { 27 | 28 | let sharedText = textField.text 29 | 30 | textLabel.text = sharedText 31 | 32 | defaults?.setObject(sharedText, forKey: key) 33 | defaults?.synchronize() 34 | } 35 | 36 | } 37 | 38 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaultsTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | com.natashatherobot.$(PRODUCT_NAME:rfc1034identifier) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /SharingWithUserDefaults/SharingWithUserDefaultsTests/SharingWithUserDefaultsTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SharingWithUserDefaultsTests.swift 3 | // SharingWithUserDefaultsTests 4 | // 5 | // Created by Natasha Murashev on 2/4/15. 6 | // Copyright (c) 2015 NatashaTheRobot. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import XCTest 11 | 12 | class SharingWithUserDefaultsTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | XCTAssert(true, "Pass") 27 | } 28 | 29 | func testPerformanceExample() { 30 | // This is an example of a performance test case. 31 | self.measureBlock() { 32 | // Put the code you want to measure the time of here. 33 | } 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /WatchKitArchitecture.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/NatashaTheRobot/watchkit/3e05c122b289bfcfcd57cd2f1405cf19b61b1546/WatchKitArchitecture.pdf --------------------------------------------------------------------------------