おおまかな手順は次のとおりです。
現在のxcdatamodelファイルをModel.xcdatamodelとします。
1.Xcode左ペインで Model.xcdatamodel を選択する。
2.メニューのEditorから"Add Model Version..."を選択する。
3.保存名(デフォルト:Model 2.xcdatamodel)、保存先を設定/選択する。
4.保存すると、次のようなModel.xcdatamodeldが作られる。
Model.xcdatamodeld
Model.xcdatamodel
Model 2.xcdatamodel
5.Model 2.xcdatamodelをカレントモデルに設定する。
6.自動マイグレーションのためのコードを実装する。
自動マイグレーションの実装例
(Core Dataの追加でメソッドを実装した場合)
MYAppDelegate.m
#import "MYAppDelegate.h"
#import "Person.h"
@implementation MYAppDelegate
{
NSManagedObjectContext *_managedObjectContext;
NSPersistentStoreCoordinator *_persistentStoreCoordinator;
NSManagedObjectModel *_managedObjectModel;
}
- (NSManagedObjectContext *)managedObjectContext {
if (_managedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return _managedObjectContext;
}
-(NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel == nil) {
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
}
return _managedObjectModel;
}
//プロパティpersistentStoreCoordinatorのgetterメソッド。
//persistentStoreCoordinatorWithOptionをoption=nilで呼び、その戻り値を返す。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
return [self persistentStoreCoordinatorWithOption:nil];
}
//オプション指定可のpersistentStoreCoordinator getterメソッド。migrarion時にオプションを追加する。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinatorWithOption:(NSDictionary *)options
{
if (_persistentStoreCoordinator == nil) {
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
NSError *error = nil;
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[self coreDataStoreURL]
options:options
error:&error])
{
//エラー処理
NSLog(@"persistentStoreCoordinator: Error %@, %@", error, [error userInfo]);
}
}
return _persistentStoreCoordinator;
}
//アプリケーションのDocumentsフォルダ。CoreDataをここに保存する。
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
//Core Data保存先。保存先がひとつだけの場合。
- (NSURL *)coreDataStoreURL
{
return [NSURL fileURLWithPath:[[self applicationDocumentsDirectory]
stringByAppendingPathComponent: @"CoreData.sqlite"]];
}
//---------- Core Data Migration 関連 ----------
//CurrentのModelと保存されているCoreDateと整合がとれているかチェック。
//不整合の場合はマイグレーションが必要なのでYESを返す。
- (BOOL)shouldPerformCoreDataMigration
{
NSError *error = nil;
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator
metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:[self coreDataStoreURL]
error:&error];
if (storeMetadata == nil)
{
return NO;
}
//NSManagedObjectModel *destinationModel = [self managedObjectModel];
BOOL isCompatibile = [[self managedObjectModel]
isConfiguration:nil
compatibleWithStoreMetadata:storeMetadata];
return !isCompatibile;
}
//Core Dataの自動マイブレーションを行う。成功した場合はYES、失敗の場合はNOを返す。
- (BOOL)performMigration
{
//自動マイグレーションのためのオプション
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
//_persistentStoreCoordinatorを作り直すためnilにし、persistentStoreCoordinatorWithOptionを呼ぶ。
_persistentStoreCoordinator = nil;
[self persistentStoreCoordinatorWithOption:options];
NSError *error;
if (error)
{
//エラー処理
NSLog(@"error: %@", error);
return NO;
}
return YES;
}
//--------- UIApplication delegate / 起動直後にマイグレーションを実行する ---------
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
NSPersistentStoreCoordinator *persistentStoreCoordinator = [self persistentStoreCoordinator];
// update
if ([self shouldPerformCoreDataMigration])
{
if ([self performMigration] == NO)
{
_persistentStoreCoordinator = nil;
}
[self persistentStoreCoordinator];
}
return YES;
}
@end
現在のxcdatamodelファイルをModel.xcdatamodelとします。
1.Xcode左ペインで Model.xcdatamodel を選択する。
2.メニューのEditorから"Add Model Version..."を選択する。
3.保存名(デフォルト:Model 2.xcdatamodel)、保存先を設定/選択する。
4.保存すると、次のようなModel.xcdatamodeldが作られる。
Model.xcdatamodeld
Model.xcdatamodel
Model 2.xcdatamodel
5.Model 2.xcdatamodelをカレントモデルに設定する。
6.自動マイグレーションのためのコードを実装する。
自動マイグレーションの実装例
(Core Dataの追加でメソッドを実装した場合)
MYAppDelegate.m
#import "MYAppDelegate.h"
#import "Person.h"
@implementation MYAppDelegate
{
NSManagedObjectContext *_managedObjectContext;
NSPersistentStoreCoordinator *_persistentStoreCoordinator;
NSManagedObjectModel *_managedObjectModel;
}
- (NSManagedObjectContext *)managedObjectContext {
if (_managedObjectContext == nil) {
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setPersistentStoreCoordinator:coordinator];
}
}
return _managedObjectContext;
}
-(NSManagedObjectModel *)managedObjectModel
{
if (_managedObjectModel == nil) {
_managedObjectModel = [NSManagedObjectModel mergedModelFromBundles:nil];
}
return _managedObjectModel;
}
//プロパティpersistentStoreCoordinatorのgetterメソッド。
//persistentStoreCoordinatorWithOptionをoption=nilで呼び、その戻り値を返す。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinator
{
return [self persistentStoreCoordinatorWithOption:nil];
}
//オプション指定可のpersistentStoreCoordinator getterメソッド。migrarion時にオプションを追加する。
- (NSPersistentStoreCoordinator *)persistentStoreCoordinatorWithOption:(NSDictionary *)options
{
if (_persistentStoreCoordinator == nil) {
_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:[self managedObjectModel]];
NSError *error = nil;
if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType
configuration:nil
URL:[self coreDataStoreURL]
options:options
error:&error])
{
//エラー処理
NSLog(@"persistentStoreCoordinator: Error %@, %@", error, [error userInfo]);
}
}
return _persistentStoreCoordinator;
}
//アプリケーションのDocumentsフォルダ。CoreDataをここに保存する。
- (NSString *)applicationDocumentsDirectory {
return [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject];
}
//Core Data保存先。保存先がひとつだけの場合。
- (NSURL *)coreDataStoreURL
{
return [NSURL fileURLWithPath:[[self applicationDocumentsDirectory]
stringByAppendingPathComponent: @"CoreData.sqlite"]];
}
//---------- Core Data Migration 関連 ----------
//CurrentのModelと保存されているCoreDateと整合がとれているかチェック。
//不整合の場合はマイグレーションが必要なのでYESを返す。
- (BOOL)shouldPerformCoreDataMigration
{
NSError *error = nil;
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator
metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:[self coreDataStoreURL]
error:&error];
if (storeMetadata == nil)
{
return NO;
}
//NSManagedObjectModel *destinationModel = [self managedObjectModel];
BOOL isCompatibile = [[self managedObjectModel]
isConfiguration:nil
compatibleWithStoreMetadata:storeMetadata];
return !isCompatibile;
}
//Core Dataの自動マイブレーションを行う。成功した場合はYES、失敗の場合はNOを返す。
- (BOOL)performMigration
{
//自動マイグレーションのためのオプション
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
//_persistentStoreCoordinatorを作り直すためnilにし、persistentStoreCoordinatorWithOptionを呼ぶ。
_persistentStoreCoordinator = nil;
[self persistentStoreCoordinatorWithOption:options];
NSError *error;
if (error)
{
//エラー処理
NSLog(@"error: %@", error);
return NO;
}
return YES;
}
//--------- UIApplication delegate / 起動直後にマイグレーションを実行する ---------
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
NSPersistentStoreCoordinator *persistentStoreCoordinator = [self persistentStoreCoordinator];
// update
if ([self shouldPerformCoreDataMigration])
{
if ([self performMigration] == NO)
{
_persistentStoreCoordinator = nil;
}
[self persistentStoreCoordinator];
}
return YES;
}
@end
0 件のコメント:
コメントを投稿