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):
[code]
– (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;
}
[/code]
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)…
[code]
– (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;
}
[/code]
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.
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”.
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”];
Thanks that was *very* useful!
can not work in xcode4 !?
Yes, I believe it works in Xcode 4 – there’s another comment by Vincent about some Xcode4 details.
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 ?
Right. The user should never see this – it should upgrade their db when they install the new version.
works just fine in xcode 4!
Comments are closed.