The Background
Rather than merging all models in the bundle, I've specified the two models I want to use (model 1 and the new version of model 2) and merged them using modelByMergingModels:
This doesn't seem right. Why merge the models? You want to use model 2, migrating your store from model 1.
From the NSManagedObjectModel class reference
modelByMergingModels:
Creates a single model from an array of existing models.
You don't need to do anything special/specific with your source model (model 1).. just so long as it's in your bundle, the automatic lightweight migration process will discover and use it.
I would suggest abandoning the mapping model you created in Xcode, as I've seen terrible performance in comparison with the automatic-lightweight migrations. Your mileage may vary, my changes between models are different to yours, but i wouldn't be surprised. Try some timing with and without your own mapping model in the bundle.
/* Inferred mapping */
NSError *error;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,nil];
NSPersistentStore *migratedStore = [persistentStoreCoordinator addPersistentStoreWithType:nil
configuration:nil
URL:self.storeURL
options:options
error:&error];
migrationWasSuccessful = (migratedStore != nil);
You can verify in your code that your source model is available, by attempting to load it and verify that it is not nil:
NSString *modelDirectoryPath = [[NSBundle mainBundle] pathForResource:@"YourModelName" ofType:@"momd"];
if (modelDirectoryPath == nil) return nil;
NSString *modelPath = [modelDirectoryPath stringByAppendingPathComponent:@"YourModelName"];
NSURL *modelFileURL = [NSURL fileURLWithPath:modelPath];
NSManagedObjectModel *modelOne = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelFileURL];
if (modelOne == nil) {
NSLog(@"Woops, Xcode lost my source model");
}
else {
[modelOne release];
}
This assumes in your project you have a resource "YourModelName.xcdatamodeld" and "YourModelName.xcdatamodel" within it.
Also, you can check if that model is compatible with your existing, pre-migration persistent store:
NSError *error;
NSDictionary *storeMeta = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:nil URL:self.storeURL error:&error];
if (storeMeta == nil) {
// Unable to read store meta
return NO;
}
BOOL isCompatible = [modelOne isConfiguration:nil compatibleWithStoreMetadata:storeMeta];
That code assumes you have a method -storeURL
to specify where the persistent store is loaded from.