I am trying to do a migration
I have 2 versions of model
1.xcdatamodel
2.xcdatamodel
I created a mapping model from version 1 to 2
1to2.xcmappingmodel
The problem is that it can't find the migration model that I created so mappingModel always gets nil. Is there anything I have to do to specify what mappingModel it ahould use?
开发者_C百科target = [[NSManagedObjectModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]];
//target and source are initialized correctly
mappingModel = [NSMappingModel mappingModelFromBundles:nil forSourceModel:source destinationModel:target];
It might be that you changed one of your models after creating the mapping model.
Even if a change does not seem relevant it will change the hash value of the model which is used for finding the appropriate mapping model. At least I've been bitten by this just now :-)
If you've already created a mapping model from 1.xcdatamodel to 2.xcdatamodel, and properly configured it, then you should be able to do something like this: [Note: the key is specifying NSMigratePersistentStoresAutomaticallyOption]
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
if (persistentStoreCoordinator)
return persistentStoreCoordinator;
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"MyStore.sqlite"]];
NSError *error = nil;
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, nil];
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:storeUrl
options:options
error:&error])
{
// Handle error
NSLog(@"Error adding persistent store...%@", error);
// Handle the error.
NSLog(@"Failed to save to data store: %@", [error localizedDescription]);
NSArray* detailedErrors = [[error userInfo] objectForKey:NSDetailedErrorsKey];
if(detailedErrors != nil && [detailedErrors count] > 0)
{
for(NSError* detailedError in detailedErrors)
{
NSLog(@" DetailedError: %@", [detailedError userInfo]);
}
}
else
{
NSLog(@" %@", [error userInfo]);
}
}
else
{
DLog(@"Persistent store added without incident, apparently.");
}
return persistentStoreCoordinator;
}
To answer the original question, your code looks alright but I'm not why you passed nil as the bundles parameter. The documentation doesn't say one can. So:
NSArray *theBundles = [NSArray arrayWithObject:[NSBundle mainBundle]];
mappingModel = [NSMappingModel mappingModelFromBundles:theBundles
forSourceModel:source
destinationModel:target];
If you pass nil as bundle parameter, it will take [NSBundle mainBundle].
[To response to question of Elise van Looij]
精彩评论