iOS swiftのCoreDataをバージョン管理するために必要なAppDelegate.swiftの変更

swift+Xcode7でiOSアプリの開発をやっていて、こんな大事なことがどうしてもっと分かりやすいところに書いていないのだろうと思ったので、自分のメモ代わりにここに書いておく。

アプリの中でデータモデルを定義してmanagedObjectとして扱っているとき、アプリの機能を増やしていくと、どうしてもデータモデルの定義(RDBでいうとテーブル定義みたいなもの)を変更する必要が出てくる。

そこで〜.xcdatamodeldファイルを選択した状態で、Xcode の Editor メニューの Add Model Version… をクリックして、データモデルの新バージョンを作成する。デフォルトでは同じファイル名で末尾に半角スペースとバージョンを示す数字が2から始まって付加され、新しい〜.xcdatamodeldが、元の〜.xcdatamodeldファイルの子供のファイルとして自動生成される。

そして新しく作成された〜.xcdatamodeldファイルの方で、データモデルを変更し、親の〜.xcdatamodeldファイルを選択した状態で、Xcodeのウィンドウの右端のプロパティーの Model Version の Current で新しい方のファイルを選択すればよい。

このようにデータモデルをバージョン管理化した後、の話である。

このとき単に 〜.xcdatamodeld ファイルで Entity (RDBで言うテーブル) に Attribute (RDBで言うカラム)を追加し、対応する 〜+CoreDataProperties.swift ファイルに @NSManaged var 〜という具合に、追加した Attribute と同名の変数を追加して対応させるだけでは、コンパイル・エラーになってしまう。

実は、さらに Appelegate.swift (プロジェクト作成時にXcodeが自動で作成するファイル)内の lazy var persistentStoreCoordinator 関数の内部で NSPersistentStoreCoordinator の addPersistentStoreWithType メソッドを呼び出している部分を、下記に示す、変更前、変更後のように書き換える必要があるのだ!

変更前
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)

変更後
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: [NSMigratePersistentStoresAutomaticallyOption: true, NSInferMappingModelAutomaticallyOption: true])

NSpersistentStoreCoordinatorのインスタンスであるcoordinatorのaddPersistentStoreWithTypeメソッドの4つめの引数 options: に、2つの要素からなる配列を記述する必要があるということ。

これらは NSPersistentStoreCoordinator クラスの定数として定義されている。

一つは NSMigratePersistentStoresAutomaticallyOption で、Store Options 定数の一つとして String 型で定義されている。

もう一つは NSInferMappingModelAutomaticallyOption で、Migration Options 定数の一つとして String 型で定義されている。

これら2つのオブションをキーとし、値を true とする Dictionary 型の引数を options に渡してやると、初めてエラーなしでコンパイルでき、CoreData のデータモデルが自動的にバージョンアップされるようになる。

参考にしたのは以下のページ。

iOS Swift入門 #171】CoreDataのDataModelアップデートのため、マイグレーションする(LightWeight Migration)

Apple社の CoreData の lightweight migration についての公式文書を読んでも、上記のページにも、具体的に AppDelegate.swift 内で addPersistentStoreWithType メソッドを呼び出している部分の options を変更すればよいとまで書かれていなかったので、かなり困った。

正直iOSアプリの開発は、Apple社の公式ドキュメントにコーディング事例が全く無いので、英語で stackoverflow.com を調べまくらないと前進しない。そのあたりが Microsoft の開発者向けチュートリアルなど、公式ドキュメントのバカがつくほど親切な点との大きな違い。

やっぱり Apple ってエリート主義のにおいをプンプンと漂わせてますねぇ。それ自体が良いことだとも、悪いことだとも思わないけれど。