hachinoBlog

hachinobuのエンジニアライフ

CoreDataでThe model used to open the store is incompatible with the one used to create the storeエラー

CoreDataのモデルファイルにカラムを追加して再度ビルドしたところ下記エラーが出た。

error:{
    metadata =     {
        NSPersistenceFrameworkVersion = 419;
        NSStoreModelVersionHashes =         {
            EntityA = <3159d1ee 37851832 a788a9a2 fae591d2 4d0f7a24 73d33faf 2384d6a0 9f9d4apo>;
            EntityB = <901b07ab 1cb377c7 ebbff291 85f26131 39c837b9 f27fc74c 3f90744e d1bb008u>;
            EntityC = <049a7006 f9504dd8 e5081392 95317825 005826b0 d97c7a35 3d039fa1 66fdf4p0>;
            EntityD = <8c29ac72 2c838157 8bb8156d e3345db5 3dd7c1b7 2ec8c923 f7c2b7af 386c40ad>;
            EntityE = <126b92ca 3f7d72b9 a26b0171 6dda0d7b 0023da4a 09d31e78 b58b55b5 db30a7oi>;
            EntityF = <90896b49 ed7b8bb7 2a767349 7b555157 37db07fe 338c5484 e51b9e9b 76f6f09o>;
            EntityG = <849addf3 3cedb06c 4d87cd5c 3186986b 254a89b9 56693d72 d7daa7d6 000aai9k>;
        };
        NSStoreModelVersionHashesVersion = 3;
        NSStoreModelVersionIdentifiers =         (
            ""
        );
        NSStoreType = SQLite;
        NSStoreUUID = "0D2157EA-73B2-47EE-A76D-4C7C4E0189F1";
        "_NSAutoVacuumLevel" = 2;
    };
    reason = "The model used to open the store is incompatible with the one used to create the store";
}

調べるとSQLiteファイルが既にアプリ内に保持されていて、そのSQLiteファイルとカラムなど定義されているものが違うから出るエラーということ。
解決方法はアプリを削除してあげれば保持しているSQLiteファイルも消えるのでアプリを消して再度ビルドするとOKだよ。って文献が多かった。
しかし僕はアプリを消しても再度同じエラーが起きた。
原因は自身でトリッキーなことをしていたからだった。
というのもWEB連携しているアプリなのでSQLiteファイルをWEB側で作成し、アプリからそのSQLiteファイルをダウンロードしてアプリ内に保持していた。
アプリでモデルファイルを変更して新たにSQLiteファイルを生成するとCoreDataで自動で生成されるZ_METADATAテーブルのZ_UUIDカラムに一意のIDが生成される。このIDでモデルファイルとの整合性を検証している?ようだ。
なのでWEB側で生成するSQLiteファイルのZ_METADATAテーブルのZ_UUIDカラムの値も同じく合わせてあげないとマッチしてないよーってことで怒られていた。(もちろんその他のテーブルやカラムなども全てアプリで生成するSQLiteに合わせること。)
エラー内容の
NSStoreUUID = "0D2157EA-73B2-47EE-A76D-4C7C4E0189F1";って箇所。

分からなくて結構ハマってしまった。CoreData複雑だ。。
というかこの方法、危険な気がしてきてry...
まぁ、とりあえずこの方法で動いたよって話。

※2013/07/09追記
私がやっているようにWEB側からsqliteを配信するパターンの場合、ひな形となるsqliteファイルは必ずxcodeで生成したものでなければいけない。
xcodeで生成したsqliteと同じ構成でクエリから新しく生成したsqliteファイルではこの記事と同じエラーが出て動かなかった。
CoreData奥が深い