As discussed in a previous post there’s a bug on iOS 6.0 when migrating a persistent store from iCloud storage to local storage. iOS 6.1 seems to fix this, but introduces a new bug when migrating in the opposite direction, from local to iCloud. Apple notes this in the release notes:
Known Issues Moving data from a local sandbox to iCloud using migratePersistentStore causes a crash. Instead, manually migrate the data store by iterating over the objects in the local data store file.
I outlined the basic procedure to perform such a manual migration previously, but I recommend you use Drew McCormack’s MCPersistentStoreMigrator
class found in his iCloudCoreDataTester github repository1. This class uses your model’s NSEntityDescription
s to implement generic methods to perform a manual migration.
Here’s an example on how you can use MCPersistentStoreMigrator
:
/* Load the iCloud store, optionally migrate fallback store to iCloud */ - (BOOL)loadiCloudStoreMigrate:(BOOL)migrate error:(NSError * __autoreleasing *)error { BOOL success = YES; NSError *localError = nil; NSFileManager *fm = [NSFileManager defaultManager]; NSURL *iCloudDataURL = [fm URLForUbiquityContainerIdentifier:nil]; iCloudDataURL = [iCloudDataURL URLByAppendingPathComponent:kTransactionLogsDirectory]; NSDictionary *options = @{ NSPersistentStoreUbiquitousContentNameKey : kiCloudContentName, NSPersistentStoreUbiquitousContentURLKey : iCloudDataURL, NSMigratePersistentStoresAutomaticallyOption: @YES, NSInferMappingModelAutomaticallyOption: @YES }; if (migrate) { NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil]; MCPersistentStoreMigrator *migrator = [[MCPersistentStoreMigrator alloc] initWithManagedObjectModel:model sourceStoreURL:self.fallbackStoreURL destinationStoreURL:self.iCloudStoreURL]; migrator.destinationStoreOptions = options; [migrator beginMigration]; NSError *migrateError; /* call migrateEntityWithName:batchSize:save:error for each of your entities if (![migrator migrateEntityWithName:@"SomeEntity" batchSize:500 save:YES error:&localError]) { NSLog(@"Error migrating SomeEntity entities to iCloud: %@", migrateError); success = NO; } [migrator endMigration]; } if (success) { [self.persistentStoreCoordinator lock]; self.iCloudStore = [self.persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:self.iCloudStoreURL options:options error:&localError]; [self.persistentStoreCoordinator unlock]; success = (self.iCloudStore != nil); } if (!success) { if (localError && (error != NULL)) { *error = localError; } } return success; }
-
You should also take a look at his series of blog posts about iCloud and Core Data from May/June 2012. ↩
You can contact me on Twitter or at julien@caffeine.lu