从SwiftUI内保存核心数据失败

时间:2019-10-01 14:24:20

标签: core-data swiftui

我正在开发将Core Data与SwiftUI结合在一起的应用程序。一切顺利,直到我将更新代码放到工作表中,然后我收到了一个“ Foundation._GenericObjCError”错误,该错误为0,我认为这没有任何错误,但是我的持久性容器仍然没有更新。

此组合是否是已知问题?

我用于将条目添加到“商店”条目中的代码:

struct StoreAdd: View {
    @Environment(\.managedObjectContext)
    var managedObjectContext

    @State
    var name = ""
    @State
    var branch = ""

    var body: some View {
        VStack {
            TextField("Store name", text: $name)
            TextField("Store branch", text: $branch)
            Button(
                action: {
                    let store = Store(context: self.managedObjectContext)
                    store.id = UUID()
                    store.name = self.name
                    store.branch = self.branch.isEmpty ? nil : self.branch
                    self.managedObjectContext.persist()
                },
                label: { Text("Add")}
            )
            .disabled(name.isEmpty)
        }
        .padding(.horizontal, 20)
    }
}

persist()save()的包装。

3 个答案:

答案 0 :(得分:1)

我发现问题出在managedObjectContext的声明中。从环境中获取它不起作用,但是即使将其从环境中的父视图中获取,也可以将其作为参数传递。

答案 1 :(得分:1)

我也遇到了这个问题。我误以为@Environment var位于某种全球商店中,或者至少是每个SceneDelegate唯一的商店。

但是,似乎环境是分层的,会自动传递给它的后代,而不传递给模态。我想您是使用.sheet之类的东西来打开StoreAdd视图的。这实际上导致StoreAdd获得一个完全空的环境。我发现我可以通过执行以下操作来解决此错误:

.sheet(isPresented: $showAddSheet, content: { StoreAdd().environment(\.managedObjectContext, self.managedObjectContext) } )

我不知道这是错误还是设计使然。它确实允许一些有趣的想法,例如传递临时子上下文进行编辑。

答案 2 :(得分:0)

我的问题是我先拥有@Environment(\.managedObjectContext) static var context,然后拥有@ObservedObject var myModel: MyManagedObjectClass = MyManagedObjectClass(context: context)……显然,它不喜欢上下文是静态的。

为了让实际的NSManagedObject子类作为视图的属性来使用对其属性的绑定,除非该对象位于父视图上,则它应该是@State变量,并作为init方法的一部分进行填充风景。 (事实的根源在于视图上的该属性。)

另一种方法是仅在视图的实际保存方法中创建和设置托管对象的属性。

但是,如果您尝试创建一个@ObservedObject,该对象在创建像@ObservedObject var myModel: MyManagedObjectClass = MyManagedObjectClass(context: context)那样的视图时会被初始化,并且上下文是静态属性,那么这根本就行不通,因为创建对象时上下文将为nil。