开发者

Core Data - Migration question?

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]

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜