I'm making quite a few changes to the object model for our app upgrade release ie. entities added / removed, new attributes and relationships. It seems like the work would really add up for a proper core data migration. Since the data primarily serves as a cache to enhance the offline browsing experience. at this point doesnt really need migration I would think it would be a whole lot simpler if it were just blown away and recreated.
Based on various posts I've come across on this topic the general strategy is to
This is the code that reinitializes the objectModel
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
NSString *path = [[NSBundle mainBundle] pathForResource:@"<model name>" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
return managedObjectModel;
}
and recreating the objectModel and store with
objectManager = [RKObjectManager objectManagerWithBaseURL:
[NSString stringWithFormat:@"http://%@/v3",
[[NSBundle mainBundle] objectForInfoDictionaryKey:@"APIDomain"]]];
NSManagedObjectModel *objectModel = [self managedObjectModel];
objectManager.objectStore = [RKManagedObjectStore objectStoreWithStoreFilename:storeName usingSeedDatabaseName:nil managedObjectModel:objectModel delegate:nil];
However, I get the following error:
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '+entityForName: could not locate an NSManagedObjectModel for entity name 'UTCity''
I feel like it's pretty close since restarting the app succeeds in creating a new store runs correctly.
-PF
I think I've been able to do what you're describing by implementing a method from RKManagedObjectStoreDelegate
. The method is called when the persistent store creation fails. I simply delete the persistent store when this method is called. RestKit seems to recover from this just fine. I assume it created the new blank store next time it needs it.
- (void)managedObjectStore:(RKManagedObjectStore *)objectStore didFailToCreatePersistentStoreCoordinatorWithError:(NSError *)error {
[objectStore deletePersistentStore];
}
RKManagedObjectStore
attempts to create the persistent store at initialization, so you'll need to initialize your instance of RKManagedObjectStore
via one of the methods that accepts a delegate object. I just passed in my app delegate.
So far, this seems to work. As I continue developing, we'll see if it continues to do so.
Here is a solution to delete the persistent store altogether when migration fails.
// Core Data Persistent Store
NSError *error;
NSString *storePath = [RKApplicationDataDirectory() stringByAppendingPathComponent:@"Data.sqlite"];
NSPersistentStore __unused *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:@{NSInferMappingModelAutomaticallyOption: @YES, NSMigratePersistentStoresAutomaticallyOption: @YES}
error:&error];
// Reset the persistant store when the data model changes
if (error) {
[[NSFileManager defaultManager] removeItemAtPath:storePath
error:nil];
NSPersistentStore __unused *persistentStore = [managedObjectStore addSQLitePersistentStoreAtPath:storePath
fromSeedDatabaseAtPath:nil
withConfiguration:nil
options:nil
error:nil];
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With