[iOS][Mac] CoreData - マイグレーション[3] エラー

2010年12月8日水曜日 | Published in | 0 コメント

このエントリーをはてなブックマークに追加

Core Data でマイグレーション設定を行い実行すると次のエラーが出て落ちた。
[14647:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException',
 reason: 'Can't merge models with two different entities named 'Customer''
*** Call stack at first throw:
(
0   CoreFoundation    0x0150dbe9 __exceptionPreprocess + 185
1   libobjc.A.dylib   0x016625c2 objc_exception_throw + 47
2   CoreData          0x0037a9b9 +[NSManagedObjectModel modelByMergingModels:] + 3865
3   CoreData          0x00378fcb +[NSManagedObjectModel mergedModelFromBundles:] + 507
  :

調べてみると次の記事が見つかった。
iPhone Development: Core Data Migration Problems?

どうも下記のコードが問題のようだ。
- (NSManagedObjectModel *)managedObjectModel
{
if (managedObjectModel_ != nil) {
        returnmanagedObjectModel_;
    }

    managedObjectModel_ = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];

    returnmanagedObjectModel_;
}
上記の -[NSManagedObjectModel mergedModelFromBundles:] が新旧両方のモデルを一緒に読み込もう(merge)としてエラーになっているようだ。実際にアプリケーションパッケージの中を覗いてみると次のようになっていた。

*.momd という名のフォルダが作られてその中に新旧モデルファイル(*.mom)とバージョン管理用のファイルが入っている。-[NSManagedObjectModel mergedModelFromBundles:] はアプリケーションバンドル内のモデルファイル(*.mom)をバージョン管理を無視して読み込む(merge)しようとするようだ。なおマイグレーションを行わない初期の状態ではこのフォルダは存在せず、最初のバージョンのモデルファイル(*.mom)が一つあるだけ。

解決方法はモデルファイルの検索を NSManagedObjectModel に任せないで *.momd フォルダの位置を明示的に指定すれば良い。こんな感じ。
- (NSManagedObjectModel *)managedObjectModel
{
if (managedObjectModel_ != nil) {
        returnmanagedObjectModel_;
    }

    NSString *path = [[NSBundle mainBundle] pathForResource:@"hairConcierge" ofType:@"momd"];
    NSURL *url = [NSURLfileURLWithPath:path];
    managedObjectModel_ = [[NSManagedObjectModelalloc] initWithContentsOfURL:url];

    returnmanagedObjectModel_;
}
上記はブログで紹介されていたのと同等のコードだが、少し改良して momdフォルダ名を書かないコードにしてみた(必要だったので)。こんな感じ。
- (NSManagedObjectModel *)managedObjectModel
{
if (managedObjectModel_ != nil) {
        returnmanagedObjectModel_;
    }

    NSArray* paths = [[NSBundlemainBundle] pathsForResourcesOfType:@"momd" inDirectory:nil];
    NSURL *url = [NSURLfileURLWithPath:[paths objectAtIndex:0]];
    managedObjectModel_ = [[NSManagedObjectModelalloc] initWithContentsOfURL:url];

    returnmanagedObjectModel_;
}

Responses

Leave a Response

人気の投稿(過去 30日間)