Coredata manual migration
I'm using Core data in an iOS project. I have the data model setup for automatic data migration whenever I modify entity properties. But I recently made some changes to some entity relationships and now my app crashes with: "Can't find model for source store"
I realize that resetting the app i.e. deleting and re-installing will solve this is开发者_JAVA技巧sue, bit I have a live version already, and my users will lose all all their data!
So now I'm trying manual migration, but the iOS docs are not very helpful. For instance, I have this code which I run after creating a model mapping:
NSURL *destinationStoreURL = [NSURL fileURLWithPath:[[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent: @"import.sqlite"]];
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"db.sqlite"]];
//initialize migration manager
NSMigrationManager *migrationManager = [[NSMigrationManager alloc] initWithSourceModel:[[self persistentStoreCoordinator] managedObjectModel]
destinationModel:[[self persistentStoreCoordinator] managedObjectModel]];
//perform migration
NSError *error = nil;
NSMappingModel *mappingModel = [NSMappingModel inferredMappingModelForSourceModel:[[self persistentStoreCoordinator] managedObjectModel]
destinationModel:[[self persistentStoreCoordinator] managedObjectModel] error:&error];
if (mappingModel == nil) {
NSLog(@"No Mapping model error %@, %@", error, [error userInfo]);
}
[migrationManager migrateStoreFromURL:sourceStoreURL
type:NSSQLiteStoreType
options:nil
withMappingModel:mappingModel
toDestinationURL:destinationStoreURL
destinationType:NSSQLiteStoreType
destinationOptions:nil
error:&error];
Running this code works and resets the database, but I cant find my old data, and when I save any new data, I get an error that there is no persistent store!
Does anyone have any ideas?
The guys are right...
If it's not too late, try this: Open your “[your database].xcdatamodel” file. Then (assume you are using Xcode), go to your main menu. Select Design > Data Model > Add Model Version. This creates a new file, in our case, “[your database] 2.xcdatamodel":
Now go to Design > Data Model > Set Current Version. Doing this tells Xcode that this is the database schema that you'll be using. Now make whatever database schema changes you want. Now's probably a good time to make any code changes where your database schema change has been directly effected.
Now compile your program. This time it should load.
I encountered the same trouble. This is the first time I've actually read the IPhone Development Docs. I had to really pay attention. Now I'm all set. I actually chose lightweight migration. This code was hijacked straight from one (or several) of Apple's example programs (which often has bugs, just so you'll know... :-/ )
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory]
stringByAppendingPathComponent:DATABASENAME]];
NSError *error;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:
[self managedObjectModel]];
// Allow inferred migration from the original version of the application.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES],
NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES],
NSInferMappingModelAutomaticallyOption, nil];
//ATTENTION: YOU WERE CRASHING HERE...
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil URL:storeUrl options:options error:&error]) {
// Handle the error.
NSLog(@"WTF??? FAILED to create automatic lightweight migration. Error[%@]", error);
}
Core Data will first check if your data model is compatible with the current data store but this will not be the case if you've modified the relationships. You need to add a model version first which can be done from Xcode by selecting the data model and then choosing from the menu the option Design>Data Model>Add Model Version. You also need to set the current version of the model.
There is some good resource at Apple regarding the migration.
Did you set current version from Design Menu? Automatic migration should work after that assuming the options NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption are set to YES.
lightweight migration: For those who failed even after following the above steps!
Just make sure to rename your DATABASE.sqlite same as DATABASE.xcdatamodeld and put both of them at the same location which is under Documents directory :) good luck
精彩评论