マイグレーションの要不要は?
CoreData では属性を追加したり変更するとマイグレーションが必要になる。過去にリリースしたアプリを新しいアプリでバージョンアップする時にマイグレーションが必要かどうか判断するにはどうしたらよいか?
実装
NSPersistentStoreCoordinator を使えば良い。
こんな感じ。
- (BOOL)isRequiredMigration { CoreDataManager* manager = [CoreDataManager sharedManager]; [[[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:manager.managedObjectModel] autorelease]; NSURL* fileURL = [CoreDataManager fileURL_]; NSError* error = nil; NSDictionary* sourceMetaData = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType URL:fileURL error:&error]; if (sourceMetaData == nil) { return NO; } else if (error) { NSLog(@"Checking migration was failed (%@, %@)", error, [error userInfo]); abort(); } BOOL isCompatible = [manager.managedObjectModel isConfiguration:nil compatibleWithStoreMetadata:sourceMetaData]; return !isCompatible; }古いバージョンのアプリで使用しているメタデータと、(これから実行しようとしている)新しいアプリで使用するメタデータの比較を行えば良い。
- - - -
NSPersistentStoreCoordinator のインスタンスは1つしか作れないという制限はなく必要ならいくつでも作ることができる。これは同じDBファイルに対してもそう(ただし非スレッドセーフなので排他制御は自分で行う必要がある。その為のメソッドも用意されている)。
上記の様にマイグレーションの要不要をチェックする為に NSPersistentStoreCoordinator のインスタンスを作ることは、複数インスタンスを作る場合の利点の一つ。普通に1つの NSPersistentStoreCoordinator インスタンスだけで通常の利用とマイグレーションを一緒にやろうとした場合、起動時にDBへアクセスしようとした時に時間のかかるマイグレーションが発生して起動時間問題にひっかかるなどの弊害が出る場合がある。
他には大量のインポートを行いたい時に専用の NSPersistentStoreCoordinator インスタンスを用意する、複数のスレッドでインスタンスを持つ、などが考えられる。SQLite に対するオプションは NSPersistentStoreCoordinator の単位で設定できるので、インポートなど特殊な用途向けのオプションを設定する場合などにインスタンスを分けることが役立つ。
Responses
Leave a Response