cocoaheads pdx 2014 01 23 : coredata and icloud improvements ios7 / osx mavericks
DESCRIPTION
A brief look at some of the ways Apple has improved CoreData/iCloud integration in iOS7 and OSX Mavericks. Presented at Cocoaheads PDX 23 January 2014TRANSCRIPT
![Page 1: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/1.jpg)
Scott M. [email protected]
[email protected]@gmail.com
© 2012-2014 AutomationGarden
CoreData:Connecting to the Cloud
an Improvement
1
![Page 2: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/2.jpg)
Topics: tonight
Core Data Review iCloud
2
2
![Page 3: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/3.jpg)
Core Data Brief Review
3
3
![Page 4: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/4.jpg)
Why CoreData?
Provides an OO layer for persistent storage• Apple avoids the word “database”• You don’t need to know SQL
• Hardcoded, hacked SQL in apps is a Royal PITA to maintain
Why not just use Defaults?• Defaults doesn’t know about relationships
• The OSX defaults command has limited access to values below the top level• PlistBuddy overcomes this
• It’s up to you to decide to use Defaults or Core Data• but once you know Core Data, it’s hard to leave...
4
4
![Page 5: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/5.jpg)
Entity: Review
Default subclass of NSManagedObjectKinda-sorta like a row in a DB table• but much more OO
Can create custom Entities which utilize Inheritance Hierarchy• Group Cats and Dogs under shared abstract superclass
Mammals• Relationships
5
5
![Page 6: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/6.jpg)
Entity can contain:• Attribute
• type based on value class
• Relationship• types
• one-to-one• one-to-many• many-to-many (via “join table”)
• Returned to caller as an NSSet (unsorted)• Inverse relationships• Delete rules
• No Action/Nullify/Cascade/Deny
• Fetched Property• Returned to caller as an NSArray
Can also store fetch request(s) with an entity
6
6
![Page 7: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/7.jpg)
Core Data Stack: ReviewNSManagedObjectContext is the center of most everything we’ll need to do with Core DataNSPersistentStoreCoordinator talks directly with “database” store• 1 instance per store
• Can handle multiple concurrent instances of NSMangedObjectContext
NSPersistentStore is an object representation of data store
7
NSManagedObjectContext
NSPersistentStoreCoordinator
NSPersistentStore
NSManagedObjectModel
NSManagedObjectModel is a compiled version of the .xcdatamodel you create in Xcode
sqlite, xml, ...
7
![Page 8: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/8.jpg)
NSManagedObjectContext
The “center of the universe”NOT thread safe by default• http://stackoverflow.com/questions/10593735/
making-core-data-thread-safeNeeded for • Insertion of new NSManagedObject (or subclasses)• Fetching of NSManagedObject (or subclasses)
Handled for you automatically when you use Bindings to wire-up interface to model• Alas, no bindings on iOS (currently...)
8
8
![Page 9: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/9.jpg)
NSPersistentStore*
Each “database” store has one NSPersistentStore instance (and ONLY one) associated with itEach NSPersistentStore has one (and ONLY one) NSPersistentStoreCoordinator • communicates with NSPersistentStore
• Uses NSManagedObjectModel to know how to OO-ify the underlying store into a Core Data NSManagedObjectContext-friendly way
Multiple NSManagedObjectContext instances use a single NSPersistentStoreCoordinator• This ensures data store consistency
9
9
![Page 10: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/10.jpg)
NSManagedObjectModel
A compiled version of the .xcdatamodel you create in XcodeOften abbreviated MOM (Managed Object Model)Contains a complete description of all Entities, including their properties (attributes and relationships), fetch requests, fetch properties, etc.You may assign a version to a MOM via an identifier within the MOM or a key within the MOM’s userInfo • “v1.1”, or “build38release29a” or whatever you want
MOMs can be migrated forward• Difficult to migrate backwards
10
10
![Page 11: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/11.jpg)
Guides to Fetching & Predicates
Apple’s guides:• http://developer.apple.com/library/mac/
#documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html
• http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Predicates/predicates.html• Predicates not solely for core data
• Spotlight• In-memory filtering
• ...
11
11
![Page 12: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/12.jpg)
Predicate Basics
Most common way to create predicates: predicateWithFormat:• The predicate format string syntax is different from
regular expression syntax• The regular expression syntax is defined by the ICU—see
http://www.icu-project.org/userguide/regexp.html• You can use regex with MATCHES
• The left hand expression equals the right hand expression using a regex-style comparison according to ICU v3
• String comparisons are by default case and diacritic sensitive. You can modify an operator using the key characters c and d within square braces to specify case and diacritic insensitivity respectively, for example firstName BEGINSWITH[cd] $FIRST_NAME.
12
12
![Page 13: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/13.jpg)
Predicate Basics
Have the Predicate Format String Syntax doc handy• http://developer.apple.com/library/mac/
#documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html#//apple_ref/doc/uid/TP40001795-CJBDBHCB
13
13
![Page 14: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/14.jpg)
Review: Fetching with Core Data
14
NSManagedObjectContext *moc = [self managedObjectContext];NSEntityDescription *entityDescription = [NSEntityDescription entityForName:@"Employee" inManagedObjectContext:moc];NSFetchRequest *request = [[[NSFetchRequest alloc] init] autorelease];[request setEntity:entityDescription];
// Set example predicate and sort orderings...NSNumber *minimumSalary = ...;NSPredicate *predicate = [NSPredicate predicateWithFormat: @"(lastName LIKE[c] 'Lindsay') AND (salary > %@)", minimumSalary];[request setPredicate:predicate];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"firstName" ascending:YES];[request setSortDescriptors:[NSArray arrayWithObject:sortDescriptor]];[sortDescriptor release];
NSError* error = nil;NSArray* array = [moc executeFetchRequest:request error:&error];if (nil == array) || (nil != error){ // Deal with error...}
...
14
![Page 15: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/15.jpg)
Review: Insert/Save in Core Data
15
NSManagedObjectContext *moc = [self managedObjectContext];NSManagedObject *aUser = [NSEntityDescription insertNewObjectForEntityForName:@"User" inManagedObjectContext:moc];[aUser setValue:@"Scott" forKey:@"name"];[aUser setValue:@"Portland" forKey:@"city"];[aUser setValue:@"Oregon" forKey:@"state"];NSError *error;if (![moc save:&error]) { NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);}
15
![Page 16: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/16.jpg)
Demo Apps:
Road Trip - From “iOS Cloud Development for Dummies”
• Download examples (warts and all) from - http://www.dummies.com/go/iosclouddev
Example iOS7- http://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
Peruse ADC for anything interesting
16
16
![Page 17: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/17.jpg)
iCloud
17
17
![Page 18: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/18.jpg)
iCloudiCloud: serves iOS and Mac/PC devices• Multi-Application Ecosystem
Can store on iCloud• Key-Value Storage
• Cloud version of NSUserDefaults
• Container• Document Storage
• File• Package• Core Data
• Uses Document Service• to automagically handle changes to/from iCloud servers
iOS 5 or later• Introduced WWDC2011, released October 2011• sorry <=iOS4...
18
18
![Page 19: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/19.jpg)
iCloud
Utilizes Transaction Logs• entire data is not copied each time
Developer doesn’t worry about• making network connection• configuring iCloud itself
Programmer registers for notifications to know when changes have occurred in the cloud• and handles appropriately
Only works on devices, not on simulator
19
19
![Page 20: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/20.jpg)
iCloud EntitlementUses Entitlement called “Ubiquity Container”• Entitlement named NS*Ubiquitous
• not NS*Cloud or UI*Cloud
• Default definition uses your TeamID (or IndividualID) and your BundleID• Seen when logged into Apple Developer Member Center
• example URL:• /var/mobile/Library/Mobile Documents/
J3K73N7L25.senseption.com.neal.RoadTrip/
All need to be coordinated:• Provisioning Profile• AppID• BundleID
• com.apple.developer.ubiquity-kvstore-identifier• com.apple.developer.ubiquity-container-identifiers
20
20
![Page 21: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/21.jpg)
iCloud Entitlement Process1. On Apple Developer Member Center, enable iCloud entitlement/service/capability (for new or old app)
21
21
![Page 22: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/22.jpg)
iCloud Entitlement Process2. Create and Download Provisioning Profile
22
22
![Page 23: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/23.jpg)
iCloud Entitlement Process3. Drag Provisioning Profile into Xcode Organizer (if not done automatically)
23
NOT here
23
![Page 24: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/24.jpg)
iCloud Entitlement Process4. Enable entitlements/capabilities in the project (if not already done)
24
24
![Page 25: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/25.jpg)
iCloud Key/Value Storage
Not CoreData specific, but a nice featureConflict resolution• Simple: last change wins
Works even when iCloud not enabledStats• Up to 1024 keys• 1MB data per application• Up to 15 requests per 90 seconds
Just like NSDefaults, do NOT store any passwords here• encrypted or otherwise...
25
25
![Page 26: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/26.jpg)
iCloud Key/Value Storage// Get an app’s default storeNSUbiquitousKeyValueStore* kvStore = [NSUbiquitousKeyValueStore defaultStore];
// Register notification to see if data on the cloud has changed[[NSNotificationCenter defaultCenter] addObserver:self selector: @selector(ubiquitousKeyValueStoreDidChange:) name: NSUbiquitousKeyValueStoreDidChangeExternallyNotification object: kvStore];
// Values not stored to/from iCloud until you synchronize[kvStore synchronize];
// Store a value in the kv store[keyStore setString:@”Saved String” forKey:@"MyString"];
// Values not stored to/from iCloud until you synchronize[kvStore synchronize];
26
26
![Page 27: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/27.jpg)
iCloud Key/Value StorageReason that notification was fired is returned in notification
• Initial download from iCloud• Other device modified data (“push”)• Over iCloud quota
// Get an app’s default store- (void)ubiquitousKeyValueStoreDidChange:(NSNotification* theNotif){" NSDictionary* userInfo = [notification userInfo];// get reason for change" int reason = [[userInfo objectForKey:NSUbiquitousKeyValueStoreChangeReasonKey] intValue];// get the changed keys--ONLY the changed keys" NSArray* changedKeys = [userInfo objectForKey:NSUbiquitousKeyValueStoreChangedKeysKey];// store the changed values locally...}
27
27
![Page 28: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/28.jpg)
iCloud Container Storage
Application Container• File Storage area that is app-specific• “Sandbox”
Ubiquity Container• iCloud-specific file storage area
Data (whether document or core) is broken up sort-of-like a tiled image into chunks
• All chunks moved upon first upload to iCloud• Only changed chunks moved when changes made
28
28
![Page 29: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/29.jpg)
iCloud Container Storage
Metadata always pushed via NSMetadataQuery• Clients always know what documents are available to
them from iCloudClient pulls what it wants/needs
• Mac OS X: everything• iOS: app makes request
Data transferred peer-to-peer when possibleAutomatic conflict resolution
• You can also peruse UIDocumentStateInConflictURL Publishing
• Can include as email attachment rather than the document itself
29
29
![Page 30: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/30.jpg)
iCloud Container Storage
Container URL• The network path to desired document• Avoid getting on the main thread
To Check for iCloud availability:• iOS 6 / Mtn Lion (or later):
id token = [[NSFileManager defaultManager] ubiquityIdentityToken];if(token) ...
• iOS 5 / Lion (or later): NSURL *ubiq = [[NSFileManager defaultManager] " URLForUbiquityContainerIdentifier:nil];if (!ubiq) ...
30
30
![Page 31: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/31.jpg)
iCloud Container Storage
Asynchronous method// Register notification to see if iCloud available[[NSNotificationCenter defaultCenter] addObserver:self selector:@(handleUbiquityIdentityChanged:) name:NSUbiquityIdentityDidChangeNotification object:nil];
// Get container URL on not-the-main threaddispatch_async(dispatch_get_global_queue(DISPATCH_PRIORITY_QUEUE_DEFAULT, 0),^{ NSURL *containerURL = [[NSFileManager defaultManager]" URLForUbiquityContainerIdentifier:nil];});
31
31
![Page 32: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/32.jpg)
iCloud Document w/o Core Data
UIDocument / NSDocument1. Determine whether iCloud is enabled on device by
sending• [NSFileManager URLForUbiquityContainerIdentifier:]
• Will return something like • N42E42A42L.com.neal.RoadTrip
32
32
![Page 33: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/33.jpg)
iCloud Document w/o Core Data
2. Add file presenters• Adopt NSFilePresenter protocol• Make all changes through NSFileCoordinator object
• locks file for editing
• prevents background iCloud processes from modifying file at same time your code is
• UIDocument already conforms to NSFilePresenter3. Explicitly move your files to iCloud• Use value returned in step 1 with• [NSFileManager
setUbiquitous:itemAtURL:destinationURL:error]
33
33
![Page 34: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/34.jpg)
iCloud Document w/o Core Data
4. Handle version conflicts for a file• When multiple applications/devices save the same file
to the same container at the same time, iCloud stores both and lets the user decide which is the “right one”
5. Use running NSMetaDataQuery objects to receive notifications from applications/devices as files are added or removed
34
34
![Page 35: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/35.jpg)
iCloud Document w/o Core Data
6. Handle cases where files are in iCloud but are not fully downloaded to local application/device• File is considered fully downloaded when the
application:• Attempts to access the file• Sends the startDownloadingUbiquitousItemAtURL:error
message to NSFileManager
For a user, cloud ignorance is bliss--they just want their document• And you need to track/handle these cases yourself
35
35
![Page 36: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/36.jpg)
iCloud with Core DataDatabase, not DocumentCore Data Storage remains localCore Data Stores that support
• change logs• sqlite
• full file transfer• xml• binary
UIManagedDocument & NSPersistentStore• See http://developer.apple.com/library/ios/
#releasenotes/DataManagement/RN-iCloudCoreData/_index.html
• NSPersistentDocument not supported on iCloudiCloud itself is NOT a Persistent Store--works outside of Core Data
36
36
![Page 37: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/37.jpg)
iCloud with Core DataFeatures
• Per record conflict resolution• Three-way merge• Incremental changes only• Asynchronous Import• Lightweight schema migration
• versioning
Multiple “Local” stores as a best practice• One to hold data that doesn’t belong in the cloud• One to act as a “cache” to iCloud
• Decide if your iCloud store should be available all times
Fallback Store should exist in case user doesn’t enable/use iCloudUse Core Data Migration to pre-populate new store
37
37
![Page 38: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/38.jpg)
iCloud with Core DataUse Data Model Configurations to allow Core Data to split entities across multiple stores
• iCloud vs. LocalSingle Managed Object Context will “do the right thing”
38
38
![Page 39: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/39.jpg)
iCloud with Core Data
//add the store, use the "LocalConfiguration" to make sure state entities all end up in this store and that no iCloud entities end up in it_localStore = [_psc addPersistentStoreWithType:NSSQLiteStoreType configuration:@"LocalConfig" URL:storeURL options:nil error:&localError];
39
39
![Page 40: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/40.jpg)
iCloud with Core Data- (BOOL)loadiCloudStore:(NSError * __autoreleasing *)error{ BOOL success = YES; NSError *localError = nil; NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; NSURL *iCloudStoreURL = [self iCloudStoreURL]; NSURL *iCloudDataURL = [self.ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; NSDictionary *options = @{NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore", NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; _iCloudStore = [self.psc addPersistentStoreWithType:NSSQLiteStoreTypeconfiguration:@"CloudConfig"URL:iCloudStoreURLoptions:optionserror:&localError];
...
40
40
![Page 41: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/41.jpg)
iCloud with Core Data
1. Provide a value for NSPersistentStoreUbiquitousContentNameKey
2. Provide a value for NSPersistentStoreUbiquitousContentURLKey• the value that we saw earlier which was a URL path,
including TeamID and BundleID like • N42E42A42L.com.neal.RoadTrip
41
41
![Page 42: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/42.jpg)
iCloud with Core DataNSFileManager* fileManager = [NSFileManager defaultManager];NSURL* persistentStoreUbiquitousContentURL = [fileManager URLForUbiquityContainerIdentifier:nil];NSString* ubiquityContainerIdentifierPath = [[persistentStoreUbiquitousContentURL path] stringByAppendingPathComponent:@"RoadTripSharedPointOfInterest"];persistentStoreUbiquitousContentURL = [NSURL fileURLWithPath:ubiquityContainerIdentifierPath];options = [NSDictionary dictionaryWithObjectsAndKeys:[NSString stringWithFormat:@"%@%@", @"com.neal.coredata.itineraryR02.", appDelegate.destinationPreference], NSPersistentStoreUbiquitousContentNameKey, persistentStoreUbiquitousContentURL, NSPersistentStoreUbiquitousContentURLKey, [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
...
42
42
![Page 43: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/43.jpg)
iOS7 / OSX9 Improvements
Many unhappy campers a year ago...• API forced synchronous sync (slow...)• Apple didn’t realize how many people switched their
iCloud account info on-the-fly• And taking that into consideration was a Royal PITA for us
• Apple admitted there wasn’t a consistent paradigm• realized if the frameworks did it, we’d all be happier
Apple rearchitected iCloud / Core Data integration• Great WWDC2013 preso
• but no downloadable sample code (!)
Good source of downloadable sample codehttp://ossh.com.au/design-and-technology/software-development/sample-library-style-ios-core-data-app-with-icloud-integration/
43
43
![Page 44: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/44.jpg)
iOS7/OSX9 Changes
Fallback Store improvements• Entirely managed by CoreData
• Only one store file per iCloud account• Must be stored in local storage
• preferably App Sandbox• Storing “Local store” in the cloud as a document is now
discouraged
• Auto synched with cloud to ensure a local persistent store exists while you are offline
• Events logged to consoleCore Data: Ubiquity: peerID:StoreName - Using local storage: 1
44
44
![Page 45: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/45.jpg)
iOS7/OSX9 Changes
Asynchronous Setup• New notifications
• these:NSPersistentStoreCoordinatorStoresWillChangeNotification
NSPersistentStoreCoordinatorStoresDidChangeNotification
• encourage you to:-[NSManagedObjectContext save:]
-[NSManagedObjectContext reset:]
• this:NSPersistentStoreDidImportUbiquitousContentChangesNotification
• encourages you to:-[NSManagedObjectContext mergeChangesFromContextDidSaveNotification:]
45
45
![Page 46: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/46.jpg)
iOS7/OSX9 ChangesHandling Account Changes• Old notifications:
• this:NSUbiquityIdentityTokenDidChangeNotification
• would require you to (and handle all cases of):-[NSManagedObjectContext reset:]
-[NSPersistentStoreCoordinator removePersistentStore:]
-[NSPersistentStoreCoordinator addPersistentStore:]
• New (iOS7/OSX9):• this: (look familiar?)
NSPersistentStoreCoordinatorStoresWillChangeNotification
• encourages you to:-[NSManagedObjectContext save:]
-[NSManagedObjectContext reset:]
• which then: (look familiar?)NSPersistentStoreCoordinatorStoresDidChangeNotification
• encourages you to:-[NSManagedObjectContext save:]
46
46
![Page 47: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/47.jpg)
iCloud Accounts and Stores
Provide store URL inside App Sandbox• NOT in cloud
CoreData creates an opaque containerEach iCloud account is tied to a single local storeStore is automatically removed by CoreData when no longer neededSee WWDC2013s207 for more details on API• and sample code here
47
47
![Page 48: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/48.jpg)
iCloud Debugging
Test with multiple devicesXcode5 improvementsiOS simulator improvements
• iCloud Document Storage• iCloud Key-Value Store• Push Notifications
Core Data Logging• NSUserDefaults• com.apple.coredata.ubiquity.logLevel 3
com.apple.CoreData.SQLDebug 1
48
48
![Page 49: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/49.jpg)
iCloud DebuggingiCloud Logging
• OSXubcontrol -k 7
• iOS• iCloud Debug Provisioning Profile
• from developer.apple.com/downloads• Sync with iTunes to get logs
~/Library/Logs/CrashReporter/MobileDevice/device-name/DiagnosticLogs
Monitor Network Traffic• Wireshark
Use airplane mode to induce conflictsConfiguration Profiledeveloper.icloud.com
49
49
![Page 50: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/50.jpg)
iCloud SummaryIt’s Ubiquitous!iCloud Design Guide
• http://developer.apple.com/library/ios/documentation/General/Conceptual/iCloudDesignGuide/iCloudDesignGuide.pdf
WWDC videos• Still watch 2012 videos to get background for iOS5/6
compatibility• WWDC2013s207 also discusses changes to SQLite
interfacingCaveats
• Not cross-platform• Bad taste in people’s mouths from 2012-2013• Learning Curve• CoreData is NOT the same as a database
50
50
![Page 51: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/51.jpg)
Scott M. [email protected]
[email protected]@gmail.com
© 2012-2014 AutomationGarden
CoreData:Connecting to the Cloud
an Improvement
51
![Page 52: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/52.jpg)
Web Services
52
52
![Page 53: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/53.jpg)
Types of Web ServicesMessage-Oriented • (aka “Big web services”)
• UDDI (Universal Description Discovery and Integration)• WSDL (Web Services Description Language)• SOAP (Simple Object Access Protocol)
• “Chatty”--low signal/noise ratioResource-based• usually REST (REpresentational State Transfer)-HTTP
• Return a Representation of the Resource• XML• JSON• ?
53
Request
Response
WebServer
WebService
Request
Response
53
![Page 54: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/54.jpg)
Resource-Based Web Services
A URL resource request:• scheme://domain:port/path?querystring#fragment_id• scheme: http, https, etc.
• use https for secure requests
• domain: hostname or IP
• port (optional, scheme-dependent)• path• queryString
• fragment_id (rare in resource requests)Example:• http://maps.googleapis.com/maps/api/geocode/
json?sensor=false&address=17 SE 3rd Avenue, Portland, OR 97214
54
54
![Page 55: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/55.jpg)
Resource-Based Web Services in iOS
Resource representation can come back as XML or JSON• iOS is fluent in both
We’ll start with a synchronously-loaded XML example • RoadTrip 2
We can then look at an asynchronous version• RoadTrip 3
Exercises “for the reader” that we don’t address here• JSON parse (instead of XML)• Creating your own web services
55
55
![Page 56: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/56.jpg)
Road Trip 2
We create a WSManager class and use synchronous URL to get XML and then parse it• See addLocation:...
• which calls geocodeSynchronouslyXML
56
56
![Page 57: CocoaHeads PDX 2014 01 23 : CoreData and iCloud Improvements iOS7 / OSX Mavericks](https://reader033.vdocuments.net/reader033/viewer/2022060108/554f3948b4c905471e8b48d7/html5/thumbnails/57.jpg)
Road Trip 3
Asynchronous URL connection requires a delegate and support of the following delegate methods• Specified in Protocol NSURLConnectionDelegate
• primary• connection:didReceiveResponse:• connection:didReceiveData:• connection:didFailWithError:• connectionDidFinishLoading:
• optional• connection:willCacheResponse:• connection:willSendRequest:redirectResponse:• connection:didReceiveAuthenticationChallenge:• connection:didCancelAuthenticationChallenge:
• See addLocation:...• which calls geocodeAsynchronouslyXML
57
57