概要
SwiftData使用時に、
Thread 1: Fatal error: failed to find a currently active container for xxxxxxx
というエラーが出た時の原因を二つ確認しているので、備忘も兼ねて書いておきます。
.modelContainer(for: xxxx.self)を宣言していない
SwiftDataの導入直後によくあるのが、Appファイル上に.modelContainer(for: xxxx.self)
(xxxxはModel名)を宣言していないが故に発生する問題です。
Appファイルというのはプロジェクト作成時にプロジェクト名で自動的に生成されるファイルのことを指します。
例えば、SwiftDataDemo
という名前でプロジェクトを生成した場合、SwiftDataDemoApp
という名称で、以下のようにAppファイルが生成されます。
その中に、modelContainer
を宣言しておかないと掲題のエラーが発生し、アプリがクラッシュします。
import SwiftUI
@main
struct SwiftDataDemoApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.modelContainer(for: SiteInfo.self) // これがないと落ちる
}
}
}
上記の例では以下のようなSiteInfo
モデルを宣言しているため、SiteInfo.self
を宣言しています。
import Foundation
import SwiftData
@Model
final class SiteInfo {
var name: String
var code: String
let createdAt: Date
init(name: String,code: String) {
self.name = name
self.code = code
createdAt = Date()
}
}
一度作成したSwiftDataの構造を変更した場合
SwiftData内にデータを保持している状態で@Model
のついているクラスを更新し、アプリ上でデータを操作しようとするとアプリがクラッシュします。
例えば、
1.SiteInfo
内にデータを追加する
2.以下のようにSiteInfo
を更新する
3.アプリ上でSiteInfo
に関する操作を行う
上記の手順で操作を行うとアプリがクラッシュします。
import Foundation
import SwiftData
@Model
final class SiteInfo {
var name: String
var code: String
let createdAt: Date
+ var createdBy:String // 追加する
+ init(name: String,code: String,createdBy: String) {
self.name = name
self.code = code
+ self.createdBy = createdBy
createdAt = Date()
}
}
これは元々持っているデータとの不整合が発生するためにエラーが発生するようで、操作するクラス内に存在している全てのデータを削除したうえで操作を行う、ということでクラッシュを回避できます。
アプリを削除するのが手っ取り早い方法です。
その内他にもSwiftData周りのエラーやTipsについて記事をまとめていこうと思います。