Slide 1

Slide 1 text

These are confidential sessions—please refrain from streaming, blogging, or taking pictures Session 227 Using iCloud with Core Data Adam Swift Senior Software Engineer

Slide 2

Slide 2 text

Introduction •Take app from idea to iCloud •Beyond the API •Real-world strategies

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

Sample Code https://developer.apple.com/wwdc/schedule/details.php?id=227

Slide 5

Slide 5 text

Before We Begin…

Slide 6

Slide 6 text

Core Data Persistent Store

Slide 7

Slide 7 text

Core Data Persistent Store Managed Object Context

Slide 8

Slide 8 text

Core Data + iCloud

Slide 9

Slide 9 text

Core Data + iCloud

Slide 10

Slide 10 text

Core Data + iCloud

Slide 11

Slide 11 text

Core Data iCloud Features •Per record conflict resolution •Three-way merge

Slide 12

Slide 12 text

Three-Way Merge Preserve changes between systems John Doe john@.com

Slide 13

Slide 13 text

Three-Way Merge Preserve changes between systems Johnny Doe john@.com John Doe john@.com

Slide 14

Slide 14 text

Three-Way Merge Preserve changes between systems Johnny Appleseed john@.com Johnny Doe john@.com John Doe john@.com

Slide 15

Slide 15 text

Three-Way Merge Preserve changes between systems John Doe johnny@.com Johnny Appleseed john@.com Johnny Doe john@.com John Doe john@.com

Slide 16

Slide 16 text

Three-Way Merge Preserve changes between systems John Doe johnny@.com Johnny Appleseed john@.com Johnny Doe john@.com John Doe john@.com Johnny Appleseed johnny@.com

Slide 17

Slide 17 text

Core Data iCloud Features •Transfer incremental changes •Asynchronous import •Lightweight schema migration

Slide 18

Slide 18 text

What You Need •Xcode and OS X/iOS SDK ■ Core Data project template (or Sample Code) ■ iCloud Entitlements

Slide 19

Slide 19 text

What You Need •Xcode and OS X/iOS SDK ■ Core Data project template (or Sample Code) ■ iCloud Entitlements •Provisioning Portal ■ App ID for iCloud ■ Provisioning Profile

Slide 20

Slide 20 text

Launch Lifecycle Design

Slide 21

Slide 21 text

Launch Lifecycle Design

Slide 22

Slide 22 text

User Expectations •What data in iCloud? •Consider the variables ■ Network ■ Account ■ Data

Slide 23

Slide 23 text

Where Does the Data Go? •Different types of apps •Where does app data live? ■ All in iCloud ■ Some in iCloud, some local

Slide 24

Slide 24 text

Where Does the Data Go? •Different types of apps •Where does app data live? ■ All in iCloud ■ Some in iCloud, some local

Slide 25

Slide 25 text

•Data goes into iCloud What Goes into iCloud? Persistent Store

Slide 26

Slide 26 text

•Data goes into iCloud •Not Persistent Store file! What Goes into iCloud? Persistent Store Never open an SQLite database in iCloud

Slide 27

Slide 27 text

•Data goes into iCloud •Not Persistent Store file! •Data transferred as incremental changes via iCloud What Goes into iCloud? Persistent Store

Slide 28

Slide 28 text

Persistent Store as Cache •Data in iCloud •Access via Persistent Store •Rebuild from data in iCloud

Slide 29

Slide 29 text

Persistent Store as Cache •Data in iCloud •Access via Persistent Store •Rebuild from data in iCloud Persistent Store

Slide 30

Slide 30 text

Fallback Store

Slide 31

Slide 31 text

Fallback Store •No iCloud account? ■ Provide seamless app experience ■ Create local ‘fallback’ store

Slide 32

Slide 32 text

Fallback Store •No iCloud account? ■ Provide seamless app experience ■ Create local ‘fallback’ store •Existing store (pre-iCloud app version)

Slide 33

Slide 33 text

Fallback Store •No iCloud account? ■ Provide seamless app experience ■ Create local ‘fallback’ store •Existing store (pre-iCloud app version) •Move store data into iCloud when enabled

Slide 34

Slide 34 text

•Your decision •Determined by access needs ■ Access requires iCloud account? ■ Or, allow read-only access without account? iCloud-Enabled Store Location

Slide 35

Slide 35 text

Requires iCloud account for access Put Store in iCloud Container

Slide 36

Slide 36 text

Requires iCloud account for access Put Store in iCloud Container

Slide 37

Slide 37 text

Requires iCloud account for access Put Store in iCloud Container

Slide 38

Slide 38 text

Requires iCloud account for access Put Store in iCloud Container •In container, but .nosync not transferred to iCloud

Slide 39

Slide 39 text

Requires iCloud account for access Put Store in iCloud Container •In container, but .nosync not transferred to iCloud •Removed when the account changes ■ Rebuild store from iCloud data

Slide 40

Slide 40 text

Requires iCloud account for access Put Store in iCloud Container •In container, but .nosync not transferred to iCloud •Removed when the account changes ■ Rebuild store from iCloud data •Simple ■ Guaranteed to match “ubiquitous content” ■ No iCloud? No store

Slide 41

Slide 41 text

Keep Store in Sandbox Allows read-only access without account

Slide 42

Slide 42 text

Keep Store in Sandbox •Persistent store in App Sandbox, data in iCloud •Store file survives account changes •One store per-iCloud account •Read-only access without account! ■ Use NSReadOnlyPersistentStoreOption ■ Optionally move data to fallback store Allows read-only access without account

Slide 43

Slide 43 text

Partition Data •Two Persistent Stores ■ One for local device data ■ One enables data in iCloud •Use different models or configurations Local Store iCloud Enabled

Slide 44

Slide 44 text

•Subset of entities from a data model •Create store with configuration ■ Includes only those entities •One context can access stores with different configurations (based on the same model) Model Configurations “LocalConfig” “CloudConfig”

Slide 45

Slide 45 text

•Subset of entities from a data model •Create store with configuration ■ Includes only those entities •One context can access stores with different configurations (based on the same model) Model Configurations “LocalConfig” “CloudConfig”

Slide 46

Slide 46 text

Configurations in Data Model

Slide 47

Slide 47 text

Configurations in Data Model

Slide 48

Slide 48 text

Configurations in Data Model

Slide 49

Slide 49 text

Configurations in Data Model

Slide 50

Slide 50 text

Configurations in Data Model

Slide 51

Slide 51 text

Configurations in Code cloudStore = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: cloudStoreURL options: cloudOptions error: &error];

Slide 52

Slide 52 text

Configurations in Code cloudStore = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: cloudStoreURL options: cloudOptions error: &error];

Slide 53

Slide 53 text

Configurations in Code cloudStore = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: cloudStoreURL options: cloudOptions error: &error]; localStore = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”LocalConfig” URL: localStoreURL options: localOptions error: &error];

Slide 54

Slide 54 text

Summary •User expectations •Where data goes •Store location trade-offs

Slide 55

Slide 55 text

Design Launch Lifecycle Design

Slide 56

Slide 56 text

Design Launch Lifecycle Launch

Slide 57

Slide 57 text

Launch Steps •First launch? •New device, existing data

Slide 58

Slide 58 text

Goals •Get to full UI •Evaluate status ■ Ready to go? ■ Seed? ■ Fallback? •Stay responsive

Slide 59

Slide 59 text

•Launch

Slide 60

Slide 60 text

•Launch App Launch

Slide 61

Slide 61 text

•Launch App Launch Launch UI

Slide 62

Slide 62 text

Check iCloud Status ? •Launch App Launch Launch UI

Slide 63

Slide 63 text

Signed In Check iCloud Status ? •Launch App Launch Launch UI

Slide 64

Slide 64 text

Background Queue Signed In Check iCloud Status ? •Launch App Launch Launch UI

Slide 65

Slide 65 text

Background Queue Add iCloud Store Seed Data Signed In Check iCloud Status ? •Launch Notify App Launch Launch UI

Slide 66

Slide 66 text

Background Queue Add iCloud Store Seed Data Signed In Check iCloud Status ? •Launch Notify App Launch Full UI Launch UI

Slide 67

Slide 67 text

Background Queue Add iCloud Store Seed Data Signed In Check iCloud Status ? •Launch Notify App Launch Full UI Launch UI

Slide 68

Slide 68 text

Background Queue Add iCloud Store Seed Data Signed In No Account Check iCloud Status ? •Launch Notify App Launch Full UI Launch UI

Slide 69

Slide 69 text

Background Queue Background Queue Add iCloud Store Seed Data Signed In No Account Check iCloud Status ? •Launch Notify App Launch Full UI Launch UI

Slide 70

Slide 70 text

Background Queue Background Queue Add Fallback Store Prep Fallback Store Add iCloud Store Seed Data Signed In No Account Check iCloud Status ? Notify •Launch Notify App Launch Full UI Launch UI

Slide 71

Slide 71 text

Background Queue Background Queue Add Fallback Store Prep Fallback Store Add iCloud Store Seed Data Signed In No Account Check iCloud Status ? Notify •Launch Notify App Launch Full UI Launch UI

Slide 72

Slide 72 text

•Launch •Check iCloud Status -init // Get token for iCloud user account id currentToken = [fileManager ubiquityIdentityToken]; isiCloudSignedIn = (currentToken != nil);

Slide 73

Slide 73 text

•Launch •Check iCloud Status -init // Get token for iCloud user account id currentToken = [fileManager ubiquityIdentityToken]; isiCloudSignedIn = (currentToken != nil);

Slide 74

Slide 74 text

•Launch •Check iCloud Status •Add Persistent Store - (void)loadPersistentStores { queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_async(queue, ^(void) { [self asyncLoadPersistentStores]; }); } -loadPersistentStores

Slide 75

Slide 75 text

•Launch •Check iCloud Status •Add Persistent Store - (BOOL)loadiCloudStore { NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudStoreURL = [self iCloudStoreURL]; iCloudDataURL = [ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; ... NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: iCloudStoreURL options: options error: &localError]; -loadiCloudStore

Slide 76

Slide 76 text

•Launch •Check iCloud Status •Add Persistent Store - (BOOL)loadiCloudStore { NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudStoreURL = [self iCloudStoreURL]; iCloudDataURL = [ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; ... NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: iCloudStoreURL options: options error: &localError]; -loadiCloudStore

Slide 77

Slide 77 text

•Launch •Check iCloud Status •Add Persistent Store - (BOOL)loadiCloudStore { NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudStoreURL = [self iCloudStoreURL]; iCloudDataURL = [ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; ... NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: iCloudStoreURL options: options error: &localError]; -loadiCloudStore

Slide 78

Slide 78 text

•Launch •Check iCloud Status •Add Persistent Store - (BOOL)loadiCloudStore { NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudStoreURL = [self iCloudStoreURL]; iCloudDataURL = [ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; ... NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: iCloudStoreURL options: options error: &localError]; -loadiCloudStore

Slide 79

Slide 79 text

•Launch •Check iCloud Status •Add Persistent Store - (BOOL)loadiCloudStore { NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudStoreURL = [self iCloudStoreURL]; iCloudDataURL = [ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; ... NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: iCloudStoreURL options: options error: &localError]; -loadiCloudStore

Slide 80

Slide 80 text

•Launch •Check iCloud Status •Add Persistent Store - (BOOL)loadiCloudStore { NSFileManager *fm = [[NSFileManager alloc] init]; _ubiquityURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudStoreURL = [self iCloudStoreURL]; iCloudDataURL = [ubiquityURL URLByAppendingPathComponent:@"iCloudData"]; ... NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : @"iCloudStore" NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL }; [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: @”CloudConfig” URL: iCloudStoreURL options: options error: &localError]; -loadiCloudStore

Slide 81

Slide 81 text

•Launch •Check iCloud Status •Add Persistent Store •Seed Initial Data - (void)asyncLoadPersistentStores { ... if ([self loadiCloudStore]) { ... [self seedPersistentStore:_iCloudStore withPersistentStoreAtURL:[self seedStoreURL] error:&error]; } } -asyncLoadPersistenStores

Slide 82

Slide 82 text

•Launch •Check iCloud Status •Add Persistent Store •Seed Initial Data •Notify Store Ready [[NSNotificationCenter defaultCenter] addObserver: rootViewController selector: @selector(reloadFetchedResults:) name: NSPersistentStoreCoordinatorStoresDidChangeNotification object: psc]; -application:didFinishLaunchingWithOptions:

Slide 83

Slide 83 text

•Launch •Check iCloud Status •Add Persistent Store •Seed Initial Data •Notify Store Ready [[NSNotificationCenter defaultCenter] addObserver: rootViewController selector: @selector(reloadFetchedResults:) name: NSPersistentStoreCoordinatorStoresDidChangeNotification object: psc]; -application:didFinishLaunchingWithOptions:

Slide 84

Slide 84 text

•Launch •Check iCloud Status •Add Persistent Store •Seed Initial Data •Notify Store Ready •Full UI!

Slide 85

Slide 85 text

Design Launch Lifecycle Launch

Slide 86

Slide 86 text

Design Launch Lifecycle Lifecycle

Slide 87

Slide 87 text

Application Lifecycle + iCloud

Slide 88

Slide 88 text

Application Lifecycle + iCloud •Seeding •Integrate changes •Responding to User Events •Performance •Debugging

Slide 89

Slide 89 text

Demo Sample application

Slide 90

Slide 90 text

Seeding Lifecycle

Slide 91

Slide 91 text

Seeding

Slide 92

Slide 92 text

Seeding

Slide 93

Slide 93 text

Seeding •Add Seed Store

Slide 94

Slide 94 text

Seeding NSPersistentStoreUbiquitousContentNameKey NSPersistentStoreUbiquitousContentURLKey •Add Seed Store

Slide 95

Slide 95 text

Seeding NSReadOnlyPersistentStoreOption NSPersistentStoreUbiquitousContentNameKey NSPersistentStoreUbiquitousContentURLKey -addPersistentStore: •Add Seed Store

Slide 96

Slide 96 text

Seeding •Add Seed Store •Migrate objects -seedPersistentStoreStore: withPersistentStoreAtURL: error: NSUInteger batchSize = 500; [fr setFetchBatchSize:batchSize]; seedObjs = [moc executeFetchRequest:fr error:&error];

Slide 97

Slide 97 text

Seeding •Add Seed Store •Migrate objects -seedPersistentStoreStore: withPersistentStoreAtURL: error: NSUInteger batchSize = 500; [fr setFetchBatchSize:batchSize]; seedObjs = [moc executeFetchRequest:fr error:&error]; for (NSManagedObject *obj in seedObjs) { [self addManagedObjectToiCloudStore:obj]; if (0 == (i % batchSize)) { if ([moc save:&error]) { [moc reset]; } } i++; }

Slide 98

Slide 98 text

Seeding •Add Seed Store •Migrate objects •Mark seed complete

Slide 99

Slide 99 text

Seeding •Add Seed Store •Migrate objects •Mark seed complete

Slide 100

Slide 100 text

Seeding •Add Seed Store •Migrate objects •Mark seed complete

Slide 101

Slide 101 text

Seeding •Add Seed Store •Migrate objects •Mark seed complete •Clean up

Slide 102

Slide 102 text

Seeding •Add Seed Store •Migrate objects •Mark seed complete •Clean up

Slide 103

Slide 103 text

Demo Seeding

Slide 104

Slide 104 text

Integrating Changes Lifecycle

Slide 105

Slide 105 text

Change Integration Managed Object Context Managed Object Context

Slide 106

Slide 106 text

Change Integration NSManagedObjectContextDidSaveNotification Managed Object Context Managed Object Context

Slide 107

Slide 107 text

Change Integration NSManagedObjectContextDidSaveNotification Managed Object Context Managed Object Context

Slide 108

Slide 108 text

Change Integration NSManagedObjectContextDidSaveNotification NSPersistentStoreDidImportUbiquitousContentChangesNotification Managed Object Context

Slide 109

Slide 109 text

Change Integration

Slide 110

Slide 110 text

Change Integration •NSManagedObjectContextDidSaveNotification ■ NSManagedObjects

Slide 111

Slide 111 text

Change Integration •NSManagedObjectContextDidSaveNotification ■ NSManagedObjects •NSPersistentStoreDidImportUbiquitousContentChangesNotification ■ NSManagedObjectIDs

Slide 112

Slide 112 text

Integrating Changes

Slide 113

Slide 113 text

Integrating Changes

Slide 114

Slide 114 text

Integrating Changes Mom

Slide 115

Slide 115 text

Integrating Changes Mom Mom

Slide 116

Slide 116 text

Integrating Changes Mom Mom

Slide 117

Slide 117 text

Integrating Changes Mom Mom

Slide 118

Slide 118 text

Integrating Changes 2 Mom 1 Mom PK Contact Mom Mom

Slide 119

Slide 119 text

Uniquing •Find the Duplicates

Slide 120

Slide 120 text

Uniquing •Find the Duplicates select zemailaddress, count(zemailaddress) from zperson group by zemailaddress; -deDupe:

Slide 121

Slide 121 text

Uniquing •Find the Duplicates select zemailaddress, count(zemailaddress) from zperson group by zemailaddress; zemailddress count(zemailaddress) [email protected] 1 [email protected] 1 [email protected] 256 -deDupe:

Slide 122

Slide 122 text

Uniquing •Find the Duplicates -deDupe:

Slide 123

Slide 123 text

Uniquing •Find the Duplicates NSExpression *countExpr = [NSExpression expressionWithFormat:@"count:(emailAddress)"]; -deDupe:

Slide 124

Slide 124 text

Uniquing •Find the Duplicates NSAttributeDescription *emailAttr; NSFetchRequest *fr; [fr setPropertiesToFetch:[NSArray arrayWithObjects:emailAttr, countExpr, nil]]; [fr setPropertiesToGroupBy:[NSArray arrayWithObject:emailAttr]]; NSExpression *countExpr = [NSExpression expressionWithFormat:@"count:(emailAddress)"]; -deDupe:

Slide 125

Slide 125 text

Uniquing •Find the Duplicates NSAttributeDescription *emailAttr; NSFetchRequest *fr; [fr setPropertiesToFetch:[NSArray arrayWithObjects:emailAttr, countExpr, nil]]; [fr setPropertiesToGroupBy:[NSArray arrayWithObject:emailAttr]]; NSExpression *countExpr = [NSExpression expressionWithFormat:@"count:(emailAddress)"]; [fr setResultType:NSDictionaryResultType]; -deDupe:

Slide 126

Slide 126 text

Uniquing •Find the Duplicates -deDupe:

Slide 127

Slide 127 text

Uniquing •Find the Duplicates 2012-06-04 15:41:38.736 SharedCoreData[26470:10d03] CoreData: sql: SELECT t0.ZEMAILADDRESS, COUNT( t0.ZEMAILADDRESS) FROM ZPERSON t0 GROUP BY t0.ZEMAILADDRESS NSArray *countDictionaries = [moc executeFetchRequest:fr error:&error]; -deDupe:

Slide 128

Slide 128 text

Uniquing •Find the Duplicates (lldb) po countDictionaries (NSArray *) $2 = 0x07c0cb80 <_PFArray 0x7c0cb80>( { count = 1; emailAddress = "[email protected]"; }, { count = 256; emailAddress = "[email protected]"; }, { count = 1; emailAddress = "[email protected]"; }) 2012-06-04 15:41:38.736 SharedCoreData[26470:10d03] CoreData: sql: SELECT t0.ZEMAILADDRESS, COUNT( t0.ZEMAILADDRESS) FROM ZPERSON t0 GROUP BY t0.ZEMAILADDRESS NSArray *countDictionaries = [moc executeFetchRequest:fr error:&error]; -deDupe:

Slide 129

Slide 129 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects -deDupe:

Slide 130

Slide 130 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects p = [NSPredicate predicateWithFormat:@"emailAddress IN (%@)", emailsWithDupes]; [fr setPredicate:p]; -deDupe:

Slide 131

Slide 131 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects emailSort = [NSSortDescriptor sortDescriptorWithKey:@"emailAddress" ascending:YES]; [fr setSortDescriptors:[NSArray arrayWithObject:emailSort]]; p = [NSPredicate predicateWithFormat:@"emailAddress IN (%@)", emailsWithDupes]; [fr setPredicate:p]; NSArray *dupes = [moc executeFetchRequest:fr error:&error]; -deDupe:

Slide 132

Slide 132 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects •Choose a winner -deDupe:

Slide 133

Slide 133 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects ■ Ensure consistent merges across peers •Choose a winner -deDupe:

Slide 134

Slide 134 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects ■ Ensure consistent merges across peers ■ Use a record UUID or timestamp •Choose a winner -deDupe:

Slide 135

Slide 135 text

Uniquing •Find the Duplicates •Fetch Duplicate Objects ■ Ensure consistent merges across peers ■ Use a record UUID or timestamp for (NSManagedObject *dupe in duplicates) { //choose winner if (0 == (i % batchSize)) { [moc save:&error]; } i++; } •Choose a winner -deDupe:

Slide 136

Slide 136 text

Demo Uniquing

Slide 137

Slide 137 text

User Events Lifecycle

Slide 138

Slide 138 text

User Events

Slide 139

Slide 139 text

User Events •Delete from Documents & Data

Slide 140

Slide 140 text

User Events •Delete from Documents & Data

Slide 141

Slide 141 text

User Events •Delete from Documents & Data

Slide 142

Slide 142 text

User Events •Delete from Documents & Data

Slide 143

Slide 143 text

User Events •Delete from Documents & Data

Slide 144

Slide 144 text

User Events •Delete from Documents & Data

Slide 145

Slide 145 text

User Events •Delete from Documents & Data

Slide 146

Slide 146 text

User Events •Delete from Documents & Data

Slide 147

Slide 147 text

User Events •Delete from Documents & Data

Slide 148

Slide 148 text

Documents & Data User Events

Slide 149

Slide 149 text

Documents & Data User Events -presentedItemURL MyDir/Data.nosync/MyFile NSFilePresenter

Slide 150

Slide 150 text

Documents & Data User Events -presentedItemURL MyDir/Data.nosync/iCloudStore.sqlite NSFilePresenter

Slide 151

Slide 151 text

Handling Account Changes User Events

Slide 152

Slide 152 text

Handling Account Changes User Events •NSFileManager API -iCloudAccountChanged:

Slide 153

Slide 153 text

Handling Account Changes User Events •NSFileManager API NSFileManager -ubiquityIdentityToken - (void)applicationDidBecomeActive:(UIApplication *)application { id token = [[NSFileManager defaultManager] ubiquityIdentityToken]; if (![self.currentUbiquityToken isEqual:token]) { [self iCloudAccountChanged:nil]; } } -iCloudAccountChanged:

Slide 154

Slide 154 text

Handling Account Changes User Events •NSFileManager API NSFileManager -ubiquityIdentityToken NSUbiquityIdentityDidChangeNotification [notificationCenter addObserver:self selector:@selector(iCloudAccountChanged:) name:NSUbiquityIdentityDidChangeNotification object:nil]; -iCloudAccountChanged:

Slide 155

Slide 155 text

- (void)iCloudAccountChanged:(NSNotification *)notification { NSError *error = nil; [_psc removePersistentStore:self.iCloudStore error:&error]; [self loadPersistentStores]; } Handling Account Changes User Events -iCloudAccountChanged:

Slide 156

Slide 156 text

Demo User events

Slide 157

Slide 157 text

Performance and Debugging Lifecycle

Slide 158

Slide 158 text

Performance

Slide 159

Slide 159 text

Performance •-save: •Coalesce changes as appropriate •Avoid storing raw sensor data ■ CoreLocation @ 60Hz!

Slide 160

Slide 160 text

Persistent Store Performance

Slide 161

Slide 161 text

Persistent Store Performance •Memory Pressure

Slide 162

Slide 162 text

Persistent Store Performance •Memory Pressure NSFetchRequest -setFetchBatchSize: NSManagedObjectContext -save: NSManagedObjectContext -reset

Slide 163

Slide 163 text

Debugging

Slide 164

Slide 164 text

Debugging •Macs are greedy peers ■ Run at least one iCloud-enabled app (TextEdit)

Slide 165

Slide 165 text

Debugging •Macs are greedy peers ■ Run at least one iCloud-enabled app (TextEdit) •Removing data ■ Coordinated write to delete every file inside container ■ Be patient, it might take a while to propagate to all your devices

Slide 166

Slide 166 text

Debugging •Macs are greedy peers ■ Run at least one iCloud-enabled app (TextEdit) •Removing data ■ Coordinated write to delete every file inside container ■ Be patient, it might take a while to propagate to all your devices •File great bugs

Slide 167

Slide 167 text

Filing great bugs Debugging

Slide 168

Slide 168 text

Filing great bugs Debugging •Sample Application •Ubiquity Container •Console logs ■ -com.apple.coredata.ubiquity.logLevel # (1,2,3)

Slide 169

Slide 169 text

Demo Debugging

Slide 170

Slide 170 text

More Information Michael Jurewitz Technology Evangelist [email protected] Cocoa Feedback [email protected] Core Data Documentation Programming Guides, Examples, Tutorials http://developer.apple.com/ Apple Developer Forums http://devforums.apple.com

Slide 171

Slide 171 text

Related Sessions Advanced iCloud Document Storage Marina Thursday 3:15PM Core Data Best Practices Mission Wednesday 9:00AM iCloud Storage Overview Pacific Heights Tuesday 4:30PM

Slide 172

Slide 172 text

Labs Core Data Lab Developer Tools Lab A Thursday 9:00AM iCloud Storage Lab Essentials Lab B Thursday 4:30PM Core Data Lab Essentials Lab B Friday 9:00AM iCloud Storage Lab Essentials Lab B Friday 11:30AM

Slide 173

Slide 173 text

No content

Slide 174

Slide 174 text

The last 3 slides after the logo are intentionally left blank for all presentations.

Slide 175

Slide 175 text

The last 3 slides after the logo are intentionally left blank for all presentations.

Slide 176

Slide 176 text

The last 3 slides after the logo are intentionally left blank for all presentations.