在SwiftUI中将核心数据实体保存在弹出窗口中会抛出nilError,而不会再次将.environment传递给SubView

luk*_*aco 6 core-data ios swift swiftui

SwiftUI和Core Data的“玩法”使我陷入一个奇怪的问题。因此,情况如下:

我有一个主视图“ AppView”和一个名为“ SubView”的子视图。如果我单击NavigationTitleBar中的加号按钮(作为弹出窗口或工作表),将从AppView视图中打开SubView视图。

@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
        self.modal.toggle()
      }) {
        Image(systemName: "plus")
      }.popover(isPresented: self.$modal){
        SubView()
      }
Run Code Online (Sandbox Code Playgroud)

SubView视图的形式有点小,带有两个TextField对象,用于添加一个姓氏和一个姓氏。这两个对象的输入由两个单独的@State属性处理。此表单中的第三个对象是简单按钮,该按钮应将前名和姓氏保存到附加的CoreData客户实体中。

...
@Environment(\.managedObjectContext) var managedObjectContext
...
Button(action: {
  let customerItem = Customer(context: self.managedObjectContext)
  customerItem.foreName = self.forename
  customerItem.surname = self.surname

  do {
    try self.managedObjectContext.save()
  } catch {
    print(error)
  }
}) {
  Text("Speichern")
}
Run Code Online (Sandbox Code Playgroud)

如果我尝试以这种方式保存Customer实体,则会收到错误:“ nilError”,特别是:NSError中出现了“未解决的错误Error Domain = Foundation._GenericObjCError Code = 0“(null)”,[:]“。

但是在弄清楚之后,当我.environment(\.managedObjectContext, context)像这样添加到SubView()调用时,SubView().environment(\.managedObjectContext, context)它就像是一种魅力。

有谁知道,为什么我需要第二次传递managedObjectContext?我以为,我只需要传递一次managedObjectContext即可在整个视图层次结构中使用它,就像在SceneDelegate.swift中那样:

    // Get the managed object context from the shared persistent container.
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext

    // Create the SwiftUI view and set the context as the value for the managedObjectContext environment keyPath.
    // Add `@Environment(\.managedObjectContext)` in the views that will need the context.
    let contentView = AppView().environment(\.managedObjectContext, context)
Run Code Online (Sandbox Code Playgroud)

是否因为以这种方式调用SubView()而使视图不属于视图层次结构?我不明白...

kdi*_*891 36

哇这让我发疯!特别是因为错误告诉您绝对没有关于如何修复的信息。

这是解决 Xcode 中的错误之前的修复:

        .navigationBarItems(trailing:
            Button(action: {
                self.add = true
            }, label: {
                Text("Add Todo List")
            }).sheet(isPresented: $add, content: {
                AddTodoListView().environment(\.managedObjectContext, managedObjectContext)
            })
        )
Run Code Online (Sandbox Code Playgroud)

只需添加.environment(\.managedObjectContext, managedObjectContext)到您的辅助视图(在本例中为模态)。

  • 对我们现在勇敢地使用 SwiftUI 进行开发的人来说是巨大的帮助...... (11认同)