実際のところ Flutter プラグイン固有の Tips ではなく、 Pods や Framework の中から .xcdatamodeld をロードする方法の Tips ですが、iOSネイティブ開発慣れしていないと、とても分かりにくいと思ったのでメモとして残しておきます。
問題
Core Data の使い方ガイドでは、以下のようなコードでサクッと MyModel.xcdatamodeld を読み込む方法が紹介されていますが、Flutter プラグインの中に .xcdatamodeld ファイルをもたせた場合、このコードを書いても読み込めません(ちなみに、この段階ではエラーにならず、エンティティ生成時にクラッシュします)。
_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"MyModel"];
原因
問題は2点です。
- Flutter プラグインは、Flutter アプリ本体とは別のフレームワークとしてビルドされますが、Flutter プラグインの初期設定では、.xcdatamodeldがバンドルされません。
- フレームワークにうまく MyModel.xcdatamodeld をバンドルした場合でも、モデル名だけではリソースを読み込めません。フレームワーク内のリソースには、そのリソースを指すパスでアクセスする必要があります。
対策
まず、.xcdatamodeld がフレームワークにバンドルされるようにします。
次のスクリーンショットは plugin_example という名前の Flutter プラグインのフォルダ構造です。
ios/Resources フォルダを作り、そこに MyModel.xcdatamodeld ファイルを置きます。
そして、podspec に次の行を追加します。
s.resources = 'Resources/MyModel.xcdatamodeld'
次に、モデル読み込みのコードを以下のとおり書き換えます。
NSURL *modelURL = [[NSBundle bundleForClass:self.class] URLForResource:@"MyModel" withExtension:@"momd"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
_persistentContainer = [[NSPersistentContainer alloc] initWithName:@"MyModel" managedObjectModel:model];
self.class の self は Flutter プラグインに所属しているクラスのインスタンスを与えます。Flutterプラグインの初期化コードあたりに書けば良いと思います。
拡張子を momd に指定しているのは、MyModel.xcdatamodeld ファイルはビルドされ、 実際には MyModel.xcdatamodel.momd という名称でバンドルに保存されるためです。