既にリリースしたアプリケーションでCoreDataを使っていて、既存のSQLiteのテーブルにカラムを追加したいときがある。
DBがクライアント側にあるので、Railsみたいに簡単にはマイグレーションできないだろうと思っていたけど、簡単なマイグレーションなら自動でできるらしいので調べたことをまとめておく。
Apple公式 参考資料
Core Data Model Versioning and Data Migration Programming Guide
最初に、この参考資料は一応呼んでおくべきだけど、基本的には自動マイグレーションではなく完全に手動でマイグレーションを行うための情報が記載されている。自動マイグレーションについても記載されているが、何回か読まないと具体的な手順は分かりにくかった(ちゃんと読めばわかる)。
以下のような変更例であれば自動でマイグレーションできると記載されている。
- 属性(カラム)の追加
- 属性(カラム)の削除
- 必須だった属性を任意に変更
- 任意だった属性を必須に変更して、デフォルト値を指定
- エンティティ名や属性名の変更
手順
- CoreDataのモデルのバージョンを新規作成
- 新規作成したバージョンをカレントバージョンに設定
- 新規作成したバージョンに変更(属性追加など)を記述
- CoreDataのpersistentStoreを初期化時に、自動マイグレーションのオプションを渡す
1. CoreDataのモデルのバージョンを新規作成
CoreDataの定義ファイルを選択した状態で、Xcodeのメニューから、Editor -> Add Model Version を選択する
2. 新規作成したバージョンをカレントバージョンに設定
CoreDataの定義ファイルを選択した状態で、インスペクタでcurrentを新しいバージョンに設定
3. 新規作成したバージョンに変更(属性追加など)を記述
必要な変更を記述する。
追加したバージョンの方を選択してから書くこと。
モデルクラスの.hファイルや.mファイルも必要に応じて変更しておく。
4. CoreDataのpersistentStoreを初期化時に、自動マイグレーションのオプションを渡す
CoreDataのスタックを初期化する際に、以下のように自動マイグレーションのオプションを渡す。
XcodeでCoreDataの初期化処理を自動生成した場合は、AppDelegate.mとかに以下のような部分が既にあるので、オプションを渡す部分を追記する。
//CoreDataの自動マイグレーションオプションを設定 NSDictionary *options = [[NSDictionary alloc] initWithObjectsAndKeys: [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption, [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil]; _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) { NSLog(@"Unresolved error %@, %@", error, [error userInfo]); }