ModelContainer セット時には便利な、
view extension と modifier のセットですが、
複数に重なってくると、
なんだか頭が痛くなる。
再度、ModelContainer の基本的な利用の流れを整理しておきます。
👨💻 ModelContainer から ViewModifier を作成
struct DataContainerViewModifier: ViewModifier {
private let container: ModelContainer
init() {
container = try! ModelContainer(
for: Schema([Plant.self, Bird.self]),
configurations: [ModelConfiguration()]
)
}
func body(content: Content) -> some View {
content
.modelContainer(container)
}
}
👨💻 ViewModifier から extension View を作成
extension View {
func dataContainer() -> some View {
modifier(DataContainerViewModifier())
}
}
これ、#Preview など利用したい View で簡単に利用できて便利です。
👨💻 View にセットする
@main
struct SampleApp: App {
var body: some Scene {
WindowGroup {
ContentView()
.dataContainer()
}
}
}
これで この View 以下の View では、
@Query, @Environment を利用して、
データ取得、監視、操作が行えるようになりました。
👨💻 元コードを編集してみる
元のサンプルコードは、
以上の流れが、2層になっているので、
1層にして、少し見通し良くしてみました。
作成後の ModelContainer の ModelContext は、
container.mainContext
で、直接取得することができます。
👨💻 まとめ
SwiftData の基本的な構成を図でまとめておきます。
👉 Preserving your app’s model data across launches | Apple Developer Documentation
手順的には、
1. Scheme (@Model) と ModelConfiguration を作成する。
2. それらを使って ModelContainer を作成する。
3. それを使って extension View を作成する。
4. それを View にセットする。
というかんじで定型的にサンプルコードでは書いてます。
以下、参考記事。
👉 Dive deeper into SwiftData - WWDC23 - Videos - Apple Developer
👉 SwiftData Stack: Understanding Schema, Container & Context - swiftyplace
👉 View を拡張したい場合は原則として extension を使用し、状態保持が必要な場合のみ `ViewModifier` を実装する。 · YusukeHosonuma/Effective-SwiftUI · Discussion #31