1

大幅な変更が必要な iOS アプリを継承しました。現在の形式では、単一の UIManagedDocument (iCloud と同期されていませんが、Core Data ボイラープレートを回避するためにのみ使用されます) を使用してユーザー データを格納します。データ モデルを大幅に変更する必要があり、通常の Core Data スタックに切り替えたいと考えています。既存のコードベースもかなり使い物にならなかったので、新しいプロジェクトを作成することにしましたが、同じアプリ ID を使用して更新として公開できるようにしました。

既存のユーザーのデータを新しいデータ モデルにインポートする方法がわかりません。

現在のモデルには 3 つの主要なエンティティがあり、それぞれのエンティティから 2 つの属性のみが必要です (残りの古いデータは破棄できます)。新しいデータ モデルを作成した後、以前のプロジェクトのすべての古いモデル ファイルと古いデータ モデルをコピーしました。

次に、インポーター クラスを作成しました。

-(BOOL)isImportNeeded
{
    return [[NSFileManager defaultManager] fileExistsAtPath:[[self URLToOldModel] path]];
}

-(NSURL*)URLToOldModel
{
    NSURL* URL = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
    return [URL URLByAppendingPathComponent:@"Data"];
}

-(UIManagedDocument*)managedDocumentAtPath:(NSString*)path
{
    return [[UIManagedDocument alloc] initWithFileURL:[self URLToOldModel]];
}

-(void)performWithDocument:(void (^)(void))onDocumentReady
{
    if (self.managedDoc.documentState == UIDocumentStateClosed) {
        // I put this code here for debug purposes
        NSError* e = nil;
        if (![self.managedDoc readFromURL:self.managedDoc.fileURL error:&e]) {
            NSLog(@"Couldn't read UIManagedDocument: %@", [e localizedDescription]);
        }
//        [self.managedDoc openWithCompletionHandler:^(BOOL success){
//            if (success)
//                onDocumentReady();
//            else
//                NSLog(@"Could not open document");
//        }];
    }
    else if (self.managedDoc.documentState == UIDocumentStateNormal)
    {
        onDocumentReady();
    }
}

-(void)import
{
    self.managedDoc = [self managedDocumentAtPath:[[self URLToOldModel] path]];
    self.sourceManagedObjectContext = self.managedDoc.managedObjectContext;

    [self performWithDocument:^{ ... }];
}

エラーの辞書をもう少し掘り下げると、エラーの理由としてNSLog次のように表示されます。「ストアを開くために使用されたモデルは、ストアを作成するために使用されたモデルと互換性がありません」.Couldn't read UIManagedDocument: The operation couldn’t be completed. (Cocoa error 134100.)userInfo

古いデータ モデルがプロジェクトに追加され、「ソースのコンパイル」ビルド フェーズにあることを確認しました。

UIManagedDocument についてさらに学び、初期化されると、バンドル内のすべてのデータ モデルの結合が自動的に作成され、これを停止する方法は、UIManagedDocument をサブクラス化し、アクセサーをオーバーライドすることであることに気付きましたmanagedObjectModel。次のメソッドだけでサブクラスを作成することで、そうしました。

-(NSManagedObjectModel*)managedObjectModel
{
    NSString* modelPath = [[NSBundle mainBundle] pathForResource:@"Data" ofType:@"momd"];
    modelPath = [modelPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURL* modelURL = [NSURL URLWithString:modelPath];
    return [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
}

ただし、それでも同じエラーが発生します。

4

1 に答える 1

0

私の友人はこれを提案しました.これは、私がこれまでに取り組んだすべてのコアデータアプリで使用しています-どのように私を逃れたのかわかりません:

self.managedDoc.persistentStoreOptions = @{NSIgnorePersistentStoreVersioningOption: @YES,
                                           NSMigratePersistentStoresAutomaticallyOption: @YES,
                                           NSInferMappingModelAutomaticallyOption: @YES};

それでできました。

于 2013-10-26T04:37:02.400 に答える