我正在尝试编写一些代码,如果新项目尚不存在,则将其插入到 SwiftData 中。我遇到了关于
ModelContext
的错误,但我无法解决。
以下代码是精简版本,足以产生错误。我已经删除了测试现有项目的逻辑,直到我能够解决这个问题。
抱歉这么长:
import SwiftUI
import SwiftData
@Model
class TestData {
@Attribute(.unique) var id: String
var value: String
init(id: String, value: String) {
self.id = id
self.value = value
}
}
struct EditTestItem: View {
@Bindable var testData: TestData
var body: some View {
VStack {
HStack {
Text($testData.id)
TextField("Enter Data Here", text: $testData.value)
}
}
.modelContainer(for: TestData.self)
}
}
struct TestContent: View {
var testIDValue: String = ""
@Environment(\.modelContext) private var modelContext
@Query var testData: [TestData]
var testItem: TestData
init(testID: String) {
testItem = TestData(id: testID, value: "New value: \(testID)")
let _ = modelContext.insert(testItem)
do {
try modelContext.save()
} catch {
print("\(#line) oops")
}
}
var body: some View {
VStack {
VStack {
Text(testIDValue)
Text("\(testData.count)")
EditTestItem(testData: testItem)
}
Button("Save", action: {
try? modelContext.save()
})
}
.modelContainer(for: TestData.self)
.onAppear {
}
}
}
#Preview {
TestContent(testID: "b")
.modelContainer(for: TestData.self)
.frame(width: 400)
}
错误包括:
访问安装在视图之外的环境的值。这将始终读取默认值并且不会更新。
和
在视图环境中设置 .modelContext 以使用查询
肯定不是添加数据。
正确的做法是什么?
这是适合我的测试代码,将
TestData
替换为
我的 Product
模型仅供我测试。
struct ContentView: View {
@Environment(\.modelContext) private var modelContext
@Query var testData: [Product]
var testIDValue: String = ""
var testItem: Product
init() {
let testID: String = "12345" // <-- for testing
testItem = Product(sku: testID, name: testID)
}
var body: some View {
VStack {
VStack {
Text(testIDValue) // <--
Text("\(testData.count)")
EditTestItem(testData: testItem)
}
Button("Save", action: {
do {
try modelContext.save()
} catch {
print("\(#line) oops")
}
})
List {
ForEach(testData){ product in
Text(product.sku)
}
}
}
.modelContainer(for: Product.self)
// .task {
.onAppear {
let _ = modelContext.insert(testItem)
do {
try modelContext.save()
} catch {
print("\(#line) oops")
}
}
}
}