50

コアデータモデルに新しい属性を追加するときに、アプリが自動軽量移行を実行できるようにしたいと思います。

Appleのガイドでは、これが私が見つけた主題に関する唯一の情報です。

自動軽量移行

自動軽量移行をリクエストするには、addPersistentStoreWithType:configuration:URL:options:error:で渡すオプションディクショナリに適切なフラグを設定します。NSMigratePersistentStoresAutomaticallyOptionキーとNSInferMappingModelAutomaticallyOptionキーの両方に対応する値をYESに設定する必要があります。

NSError *error;
NSURL *storeURL = <#The URL of a persistent store#>;
NSPersistentStoreCoordinator *psc = <#The coordinator#>;
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
    [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
    [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
 
if (![psc addPersistentStoreWithType:<#Store type#>
    configuration:<#Configuration or nil#> URL:storeURL
    options:options error:&error]) {
    // Handle the error.
}

MyNSPersistentStoreCoordinatorは次のように初期化されます。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
    
    if (persistentStoreCoordinator != nil) {
        return persistentStoreCoordinator;
    }
    
    NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"FC.sqlite"]];
    
    NSError *error = nil;
    persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];
    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {

        NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
        abort();
    }    
    
    return persistentStoreCoordinator;
}

自動軽量移行を機能させるためにAppleコードをどこにどのように追加すればよいかわからないのですが?

4

5 に答える 5

93

これは私が自動軽量移行を行うために行ったことです(出典: http: //brainwashinc.wordpress.com/2010/01/18/iphone-coredata-automatic-light-migration/

1.アプリデリゲートで自動移行の永続ストアオプションを設定します。

persistStoreCoordinatorの作成を次のように変更します(YOURDBを置き換えます)。

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

  if (persistentStoreCoordinator != nil) {
    return persistentStoreCoordinator;
  }

  NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: @"YOURDB.sqlite"]];

  // handle db upgrade
  NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
  [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
  [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];

  NSError *error = nil;
  persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
  if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:options error:&error]) {
    // Handle error
  }

  return persistentStoreCoordinator;
}

2.データモデルをバージョン管理し、新しいファイルを編集します。

xcdatamodelファイルを選択します[デザイン]->[データモデル]->[モデルバージョンの追加](xcdatamodeldアイテムを展開します)「2」(またはそれ以降)ファイルを選択し、[デザイン]->[データモデル]->[現在のバージョンを設定](このバージョンを編集)

3.アプリデリゲートでmomdリソースを指定します。

managedObjectModelの実装をこれに変更します(YOURDBを置き換えます)

- (NSManagedObjectModel *)managedObjectModel {

  if (managedObjectModel != nil) {
    return managedObjectModel;
  }

  NSString *path = [[NSBundle mainBundle] pathForResource:@"YOURDB" ofType:@"momd"];
  NSURL *momURL = [NSURL fileURLWithPath:path];
  managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:momURL];

  return managedObjectModel;
}
于 2010-02-22T16:01:13.957 に答える
7

最初は、上記の解決策は私にはうまくいきませんでした。返されたmanagedObjectModelは0x0でした。これは、異なるモデルファイルのファイル名を変更したためだと思います。あなたが手紙に上記の指示に従うならば、それはすべてうまくいきます。

ただし、モデルファイル名を変更する場合は、「現在の」モデルファイルを手動で選択できます。たとえば、上記のモデルの追加手順を実行した後、元のモデルファイルがMYMODEL.xcdatamodelであったとすると、ディレクトリMY.xcdatamodeldになり、その下に次のようになります。 MYMODEL.xcdatamodelおよびMYMODEL2.xcdatamodelは、新しいモデルファイルの名前を任意の名前に変更します。たとえば、スペースをMYMODEL2.xcdatamodelに削除して、その内容を編集するとします。今、上記のコードで行います

NSString *path = [mainBundle pathForResource:@"MYMODEL2" ofType:@"mom" inDirectory:@"MYMODEL.momd"];
于 2010-03-14T23:08:40.800 に答える
1

これが最後の答えに追加されると思います。

バンドルリソースと.sqlite名の使用法は、最初は本当に混乱していました。バンドルリソース名はバージョンの変更に伴って変更されますか?.sqliteの名前は変更されますか?これで移行が機能するようになり、バンドルモデル名は、そのディレクトリ内のモデルバージョンの名前ではなく、すべてのモデルを含むXCode内のディレクトリ/フォルダの名前を参照していることがわかりました。

modelResource名を次のように指定すると、次のようになります。

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:modelResource withExtension:@"momd"];
NSManagedObjectModel *theManagedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

そのmodelResource名は、Xcodeのモデルのディレクトリ/フォルダです。

あなたがするとき:

    NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:storeFileName];
    NSError *error = nil;

    if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {
        // handle error
    }

storeFileNameは、Documentsフォルダー/ディレクトリにある.sqliteファイルの名前です(これはバンドルには含まれていません)。

また、あるモデルバージョンから別のモデルバージョンに移行する場合、デフォルトでは、.sqliteファイル名は同じままです。

于 2013-10-09T19:16:32.143 に答える
0

オスカー、あなたの問題に応えて、私は最初に同じことを見つけました。新しい.xcdatamodeldファイルを削除してプロジェクトに再度追加してから、再構築することをお勧めします。お役に立てば幸いです。

于 2010-12-13T02:27:51.497 に答える
0

Swift3ソリューション

1.アプリデリゲートで自動移行の永続ストアオプションを設定します。

作成したpersistentStoreCoordinatorを次のように変更します(SingleViewCoreData.sqliteを置き換えます)。

lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {


let coordinator: NSPersistentStoreCoordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.appendingPathComponent("SingleViewCoreData.sqlite")

let options = [
  NSMigratePersistentStoresAutomaticallyOption : Int(true),
  NSInferMappingModelAutomaticallyOption : Int(true)
]

do {

  try coordinator.addPersistentStore(ofType: NSSQLiteStoreType, configurationName: nil, at: url, options: options)

} catch {

  print(error)
}

return coordinator

}()

2.データモデルをバージョン管理し、新しいファイルを編集します。

xcdatamodelファイルを選択します[エディター]>[モデルバージョンの追加]-新しいモデルの名前を追加します

于 2016-11-16T09:41:53.113 に答える