This post is pieced together from these 3 sources:
- Apple doco
- iPhone Development: Core Data Migration Problems?
- What do I have to do to get Core Data to automatically migrate models?
So there’s basically 3 steps to do (BEFORE you change your xcdatamodel file):
1. Set the Persistent Store options for automatic migration:
Change your persistentStoreCoordinator creation to this (replace YOURDB):
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]];
// handle db upgrade
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
// Handle error
}
return persistentStoreCoordinator;
}
2. Version your Data Model and Edit the new file
- Select your xcdatamodel file
- Design->Data Model->Add Model Version (expand your xcdatamodeld item)
- Select the “2″ (or later) file, Design->Data Model->Set Current Version (edit this version)
3. Specify the momd resource
Change your managedObjectModel implementation to this (replace YOURRESOURCENAME)…
- (NSManagedObjectModel *)managedObjectModel {
if (managedObjectModel != nil) {
return managedObjectModel;
}
NSString *path = [[NSBundle mainBundle] pathForResource:@"YOURRESOURCENAME" ofType:@"momd"];
NSURL *momURL = [NSURL fileURLWithPath:path];
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];
return managedObjectModel;
}
Build and run!
Thanks for doing this. This would have taken me many hours but because of your dedication and willingness to share your knowledge it only took a couple minutes. Thanks again.
By: Dave on February 26, 2011
at 20:45
Thanks for your post.
If anyone is confused about Xcode 4, you need to select your model (.xcdatamodeld), then you’ll find “Add model version…” within “Editor”, and the current model version is in the right panel (you might need to un-hide it), and is called “Versioned data model”.
By: Vincent on May 4, 2011
at 03:16
This line is wrong.
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @”YOURDB.sqlite”]];
This is the correct one
NSURL *storeUrl = [[self applicationDocumentsDirectory] URLByAppendingPathComponent: @”YOURDB.sqlite”];
By: Ivan Alessandro Carosati on May 17, 2011
at 09:38
Thanks that was *very* useful!
By: Dennis on June 26, 2011
at 03:38
can not work in xcode4 !?
By: appledev on July 8, 2011
at 04:13
Yes, I believe it works in Xcode 4 – there’s another comment by Vincent about some Xcode4 details.
By: bearc0025 on July 8, 2011
at 04:45
Thanks for this developpement ! Looks to work just fine in xcode 4
If i understood well, the next release of my app should have a different “Model Current Version” and so this won’t bug for the users ?
By: Alexis on July 10, 2011
at 08:39
Right. The user should never see this – it should upgrade their db when they install the new version.
By: bearc0025 on July 11, 2011
at 06:01
works just fine in xcode 4!
By: rikco on September 28, 2011
at 09:36