酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

Swift Package Managerでマルチモジュール化しているアプリでCoreDataの.xcdatamodeldファイルが参照できない

注意:このプロジェクトではCoreDataの定義ファイルを TweetAlbum.xcdatamodeld としている。もし存在するかわからないが、本記事を読んで同じ現象でハマった方がいれば、TweetAlbumの部分は各々で読み替えていただきたい。

Appの外にあるCoreDataの.xcdatamodeldファイルを参照できない

Swift Package Manager (以下SwiftPMと記す)を使ったマルチモジュール構造でアプリを作っている。CoreDataの定義ファイル(.xcdatamodeld)をアプリに持たせるのではなくSwiftPMのCoreモジュールに持たせるとうまく参照できずに以下のエラーが発生していた。

[error] error:  Failed to load model named TweetAlbum
CoreData: error:  Failed to load model named TweetAlbum

TweetAlbum.xcdatamodeldをアプリ内に配置している段階では、以下のコードでNSPersistentContainerオブジェクトを取得できていた。

let container: NSPersistentContainer

container = NSPersistentContainer(name: "CoreData")

TweetAlbum.xcdatamodeldをSwiftPMのパッケージであるCoreモジュールに移動させた途端、うまく参照できなくなってしまった。ちなみにCoreモジュールは下図のように定義している。

解決編:Bundleから.xcdatamodeldファイルのパスを取得する

SwiftPMでマルチモジュール化している場合には、NSManagedObjectModelオブジェクトを指定して以下のようにNSPersistentContainer(name: String, managedObjectModel model: NSManagedObjectModel)を使って初期化する。

let container: NSPersistentContainer

let modelURL = Bundle.module.url(forResource: "TweetAlbum", withExtension: "momd")!
let model = NSManagedObjectModel(contentsOf: modelURL)!
container = NSPersistentCloudKitContainer(name: "TweetAlbum", managedObjectModel: model)