7

モデルバージョンは12と13の2つです。次に、ソース12と宛先13を使用してxcmappingmodel-Fileを作成しました。

NSEntityMigrationPolicyをサブクラス化し、クラスをmappingmodel-Fileに追加して目的のエンティティに追加しました。

@interface EndDateMigrationPolicy : NSEntityMigrationPolicy

ここに画像の説明を入力してください

デバイスに古いバージョン(11)をインストールした後、モデルバージョン13で現在のステータスをインストールします。アプリは実行されますが、移行メソッドが呼び出されません。私は何かが足りないのですか?

編集:これらのオプションを使用するのは正しいですか?

    NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption: @YES,
                         NSInferMappingModelAutomaticallyOption: @YES};
4

2 に答える 2

3

できる限りお答えしたいと思います。私はコア データの移行に何度も悩まされてきたので、それがどれほど苦痛であるかを知っています。1 つには、実行しようとしているのは実際には軽量の移行ではなく、軽量の移行を実行するように指示しているため、これらのオプションで移行を機能させる必要はありません。

基本的に、何らかの理由で、11 と 12 の 2 つのバージョン間で軽量でない移行を行う必要があるとします。必要なことは次のとおりです。

1->12 ライトウェイト 12->13 カスタム マイグレーション 13->(将来のバージョン) ライトウェイト マイグレーション

より良い解決策があるかもしれませんが、私はまだ見つけていません。

これはあなたを助けるためのコードです(最も難しい部分、私はすべてをオフハンドで覚えることはできません). (これは空です)

NSString *path = [[NSBundle mainBundle] pathForResource:<YOUR MODEL NAME> ofType:@"cdm"];

NSURL *backUpURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"<YOUR MODEL NAME>MigrationBackUp.sqlite"]; //or whatever you want to call your backup
NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"<YOUR MODEL NAME>.sqlite"];
NSError *err2 = nil;
NSDictionary *sourceMetadata2 =
[NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
                                                           URL:backUpURL
                                                         error:&err2];
NSManagedObjectModel *sourceModel2 = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]

                                                                 forStoreMetadata:sourceMetadata2];
NSManagedObjectModel *destinationModel2 = [self managedObjectModelForVersion:@"1.4"]; //Yeah your gonna have to get your mapping model , I'll give you this code too later
NSString *oldModel = [[sourceModel2 versionIdentifiers] anyObject];
NSLog(@"Source Model : %@",oldModel);
NSMappingModel *mappingModel = [[NSMappingModel alloc] initWithContentsOfURL:[NSURL fileURLWithPath:path]];

if (mappingModel != nil) {
    for (NSString * identifier in [mappingModel entityMappings]) {
        NSLog(@"Mapping > %@",identifier);
    }
}

次に、移行元と移行先を使用してマイグレーターを作成します。

これも後で難しい部分です。

    BOOL success = [migrator migrateStoreFromURL:backUpURL
                                        type:NSSQLiteStoreType
                                     options:nil
                            withMappingModel:mappingModel
                            toDestinationURL:storeURL
                             destinationType:NSSQLiteStoreType
                          destinationOptions:nil
                                       error:&err2];

最後に大事なことを言い忘れました(前にあなたに渡すと言いました):

- (NSManagedObjectModel *)managedObjectModelForVersion:(NSString*)version {

NSString *modelPath = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"];
if (BETWEEN_INEX(version, @"1.0", @"1.4")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
} else if (BETWEEN_INEX(version, @"1.4", @"1.5")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model 2"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
} else if (BETWEEN_INEX(version, @"1.5", @"1.6")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model 3"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
} else if (BETWEEN_INEX(version, @"1.6", @"1.7")) {
    modelPath = [modelPath stringByAppendingPathComponent:@"Model 4"];
    modelPath = [modelPath stringByAppendingPathExtension:@"mom"];
}
NSURL *modelURL = [NSURL fileURLWithPath:modelPath];
NSManagedObjectModel * oldManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSSet *vIdentifiers = [oldManagedObjectModel versionIdentifiers];
for (NSString * identifier in vIdentifiers) {
    NSLog(@"Old Model : %@",identifier);
}
return [oldManagedObjectModel autorelease];

}

これらは単なるコードの断片であることは承知していますが、問題の解決に役立つことを願っています。他に何か必要な場合は、お問い合わせください。

于 2012-11-23T18:51:14.473 に答える
1

NSInferMappingModelAutomaticallyOption を @(YES) に設定しているため、NSEntityMigrationPolicy が呼び出されていません - @(NO) である必要があります。

于 2013-01-15T03:58:52.793 に答える