Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
269 views
in Technique[技术] by (71.8m points)

ios - Core Data - lightweight migrations and multiple core data model files (xcdatamodel)

I'm having a problem performing a lightweight migration when migrating from a store that is defined by two separate xcdatamodel files.

In version 1.0 of my app, I had the models broken out into an analytics model, model-A, and everything else in model-B. When compiling, the models would be grouped together and everything proceeded smoothly.

When working on the new version, 1.1, I upgraded model-B by adding a new model version to model-B and setting that new version as active.

The issue arises when upgrading from 1.0 to 1.1. It seems Core Data checks the model store on disk (created by version 1.0) and looks for the model that describes it but is unable to find a SINGLE model that defines the entire store (model-A only covers analytics, and model-B covers everything else), so it throws a "Can’t find model for source store" error.

Has anyone found a solution for separating out models but still allowing upgrades + lightweight migrations to work without the extra hassle of defining custom migrations?

Here is the snippet of code used to load models:

    NSArray *modelNames = [NSArray arrayWithObjects:@"model-A", @"model-B", nil];
    NSMutableArray *models = [NSMutableArray array];
    for (NSString *name in modelNames)
    {
        LogInfo(@"loading model %@", name);
        NSURL *modelURL = [[NSBundle mainBundle] URLForResource:name withExtension:@"momd"];
        NSManagedObjectModel *model = [[[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL] autorelease];
        [models addObject:model];
    }

    // combine all the separate models into one big one
    objectModel = [[NSManagedObjectModel modelByMergingModels:models] retain];

    NSURL *documentsDirectory = [NSURL fileURLWithPath:[SuperFileManager documentsDirectory] isDirectory:YES];
    NSURL *storeURL = [documentsDirectory URLByAppendingPathComponent:@"database.sqlite"];
    NSError *error = nil;

    coordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:objectModel];
    NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                                  [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                                  [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption,
                                                  nil];

    if (![coordinator addPersistentStoreWithType:NSSQLiteStoreType
                                   configuration:nil
                                             URL:storeURL
                                         options:options
                                           error:&error])
    {
        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

After attending a WWDC 2012 lab and meeting with the Core Data team, it seems you are forced to put all your model info in a single xcdatamodel. CoreData is not intelligent enough to check its existing stores as a combination of the stores that created it and are still on disk. As C. Roald pointed out, you can do some processing on old xcdatamodel files, but it's quite sad that Core Data does not handle this more elegantly.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...