Reputation: 100
I am trying to move my NSPersistentStore from my app's sandbox to a shared group container so I can access CoreData from my WatchKit extension. I am currently using Core Data with iCloud and want to move the users data to the shared group container. Currently I am creating the NSPersistentStoreCoordinator as follows:
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *url = [self storeURL]; // app's Documents directory
NSError *error = nil;
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:[self iCloudPersistentStoreOptions] error:&error]) {
NSLog(@"Error adding persistent store: %@", [error localizedDescription]);
}
// rest of setup
return __persistentStoreCoordinator;
I've already setup the shared group container in my app target and WatchKit extension target and can get the NSURL for the new store location using - (NSURL *)containerURLForSecurityApplicationGroupIdentifier:(NSString *)groupIdentifier
.
How can I check whether I need to migrate or that I've already migrated so I don't attempt to migrate multiple times? Initially I was thinking of something like this, but this doesn't work as the old store URL doesn't exist
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *newURL = [self newStoreURL]; // shared group container
NSURL *oldURL = [self oldStoreURL]; // app's Documents directory
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:newURL.path] && [fileManager fileExistsAtPath:oldURL.path]) {
NSLog(@"performing migration...");
NSPersistentStore *oldStore = [__persistentStoreCoordinator persistentStoreForURL:oldURL];
NSError *migrateError = nil;
NSPersistentStore *newStore = [__persistentStoreCoordinator migratePersistentStore:oldStore toURL:newURL options:[self iCloudPersistentStoreOptions] withType:NSSQLiteStoreType error:&migrateError];
if (!newStore) {
NSLog(@"Error migrating store: %@", [migrateError localizedDescription]);
}
}
// rest of setup
return __persistentStoreCoordinator;
Upvotes: 3
Views: 670
Reputation: 16663
From what I can tell, it looks like you're pretty much there if the migration logic you posted is working. What it seems you are missing is an else if
to handle the case where you don't have a persistent store. The following should handle that case.
if (__persistentStoreCoordinator != nil) {
return __persistentStoreCoordinator;
}
NSURL *newURL = [self newStoreURL]; // shared group container
NSURL *oldURL = [self oldStoreURL]; // app's Documents directory
__persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
NSFileManager *fileManager = [NSFileManager defaultManager];
if (![fileManager fileExistsAtPath:newURL.path] && [fileManager fileExistsAtPath:oldURL.path]) {
NSLog(@"performing migration...");
NSPersistentStore *oldStore = [__persistentStoreCoordinator persistentStoreForURL:oldURL];
NSError *migrateError = nil;
NSPersistentStore *newStore = [__persistentStoreCoordinator migratePersistentStore:oldStore toURL:newURL options:[self iCloudPersistentStoreOptions] withType:NSSQLiteStoreType error:&migrateError];
if (!newStore) {
NSLog(@"Error migrating store: %@", [migrateError localizedDescription]);
}
} else if (![fileManager fileExistsAtPath:newURL.path]) {
if (![__persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:newURL options:[self iCloudPersistentStoreOptions] error:&error]) {
NSLog(@"Error adding persistent store: %@", [error localizedDescription]);
}
}
// rest of setup
return __persistentStoreCoordinator;
Upvotes: 1