2011-06-29 14 views
12

コアデータに2つのオブジェクトモデル(v1とv2など)があります。この移行は、軽量移行に適しています。今、マイグレーションの後で、v1からv2へのマイグレーション時にのみ、カスタムコードを実行したいと思います。後でv3を導入すると、私はカスタムコードを実行させたくありません。特定のバージョンの軽量移行後のカスタムコードの実行

これを行う方法はありますか?事前に

おかげで、 アヌパム

+0

を誰かが私を助けてくださいことはできますか? –

+0

前回私はこのようなことをしたいと思っていましたが、私はカスタムマイグレーションを行ってしまいました...しかし、最終的なカスタムステップのみを含めることができれば、しばしばマイグレーションの大部分が軽量になることがあります。 Bountyさんは、この問題にさらに注意を喚起し、誰かがこれに対して良い答えを持っているかどうかを確認するために追加しました。 –

答えて

1

これは動作するはずです購入、より良い方法があるかもしれません:

は、「情報」という名前のコアデータ内のエンティティを維持することにより、DBのバージョンを追跡し、持っていますプロパティは "CoreDataVersion"という名前です。

移行コードの終了後、コアデータのバージョン番号を確認するコードを追加します。

"CoreDataVersion"の値が "v1"で、アプリケーションが現在 "v2"(これは各バージョンでハードコード可能)の場合は、追加のカスタムコードを実行してから、新しいバージョンをDBに書き戻します。

すでに「V1」は、ユーザーに公開している場合は、単にDBには「CoreDataVersion」がない場合、それは「V1」であると言います。

1
- (void) _performMaintanaceUpdate:(NSUInteger) newVersion oldVersion:(NSUInteger) oldVersion { 
      if (newVersion>=1020500 && oldVersion < 1020500) { 
       NSString *storePath = [[PreferenceDataModel getDataPath] stringByAppendingPathComponent: @"wcal.sqlite"]; 
       NSFileManager *fileManager = [NSFileManager defaultManager]; 
       if ([fileManager fileExistsAtPath:storePath]) { 
         [fileManager removeItemAtPath:storePath error:NULL]; 
       } 
       [PreferenceDataModel setVersionOfLastMaintanace:newVersion]; 
      } 
} 

(void) _checkAndPerformMaintenance{ 
    NSString* strVersion = [PreferenceDataModel getApplicationVersion]; 
    //legal version is xx.xx.xx where x is a dec digit 1.2 or 1.2.33 is legit 
    NSUInteger ver = 0; 
    NSUInteger finalVer = 0; 
    int t = 3; 

    for (int i=0; i<[strVersion length]; i++) { 
     char c = [strVersion characterAtIndex:i]; 
     if (isdigit(c)) { 
      ver*=10; 
      ver+=c - 48; 
     } 
     else { 
      finalVer+= ver * pow(100, t--); 
      ver = 0; 
     } 
    } 
    finalVer+= ver * pow(100, t); 
    [self _performMaintanaceUpdate:finalVer oldVersion:[PreferenceDataModel getVersionOfLastMaintanace]]; 
} 

と、これは、あなたが自動移行を行う永続ストアを作成する前に、あなたがバージョン2に移行されます場合は、あなたがする場合は、決定あなたがアプリケーションを取得する方法バージョン

+(NSString *) getApplicationVersion { 
    return [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; 
} 
1

です移行後に変更を行うフラグを設定します。

NSString *path = [[NSBundle mainBundle] pathForResource:@"Model" ofType:@"momd"]; 
NSURL *momURL = [NSURL fileURLWithPath:path]; 
managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL]; 
NSString *version = [managedObjectModel.versionIdentifiers anyObject]; 

識別子がXcodeで設定されているバージョン:あなたはから移行することがありますか決定するために

は、これを行います。

10

はWWDC 2010でApple社のエンジニアにより示唆されるように、基本的に店舗のメタデータを使用することによって、この状況を処理する方法である:

  • オープンカスタムキーの(移行オプション付き)ストア
  • チェックメタデータ、例えば"DonePostProcessing"
  • 後処理を行います...
    • 移入属性
    • 挿入を導出またはオブジェクト
    • 設定ストアのメタデータ(「DonePostProcessing」= YES)

    多かれ少なかれ

  • 変更を保存し、メタデータ、

    のようなものを削除します

    

    - (void)loadStoreWithMigration:(NSURL *)url { 
        ... 
    
        store = [psc addPersistentStoreWithType: NSSQLiteStoreType configuration: nil URL: url options: opts error: &err]; 
    
        m = [store metadata]; 
        key = @”DonePostProcessing”; 
        if (m && ([[m objectForKey: key] integerValue] < 2)){ 
         [self doPostProcessingInContext: context]; 
         m2 = [[m mutableCopy] autorelease]; 
         [m2 setObject: [NSNumber numberWithInteger: 2] forKey: key]; 
         [store setMetadata: m2]; 
    
         ok = [context save:&err]; 
        } 
    
    } 
    
  • +0

    アルゴリズムを変更するたびに更新する必要がある計算フィールドがあるので、これは私にとっては完璧なソリューションです。ありがとう! – phatmann

    0

    私のためによく働い別の解決策:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 
        NSInteger currVersion = [defaults integerForKey:@"dataModelVersion"]; 
        NSString *version = [managedObjectModel.versionIdentifiers anyObject]; 
        if (currVersion == 0) { 
         [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"]; 
        } 
        else if (currVersion < [version integerValue]) { 
         NSLog(@"Migration Code"); 
         [defaults setInteger:[version integerValue] forKey:@"dataModelVersion"]; 
        } 
    
    関連する問題