Jugar con SwiftUI y Core Data me llevó a un curioso problema. Entonces la situación es la siguiente:
Tengo una vista principal "AppView" y una vista secundaria llamada "SubView". La vista SubView se abrirá desde la vista AppView si hago clic en el botón más en NavigationTitleBar como popover u hoja.
@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
self.modal.toggle()
}) {
Image(systemName: "plus")
}.popover(isPresented: self.$modal){
SubView()
}
La vista SubView tiene una pequeña forma con dos objetos TextField para agregar un nombre y un apellido. Las entradas de estos dos objetos son manejadas por dos propiedades @State separadas. El tercer objeto en este formulario es un botón simple, que debe guardar el nombre y el apellido en una entidad de cliente adjunta para 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")
}
Si trato de guardar la entidad del Cliente de esta manera, obtengo el error: "nilError", especialmente: "Error no resuelto Error Domain = Foundation._GenericObjCError Code = 0" (nulo) ", [:]" de NSError.
Pero después de descubrirlo, eso cuando agrego .environment(\.managedObjectContext, context)
a la llamada SubView () así SubView().environment(\.managedObjectContext, context)
funciona de maravilla .
¿Alguien sabe por qué necesito pasar el objeto de contexto gestionado por segunda vez? Pensé, que solo necesito pasar el contexto de objeto gestionado una vez para usarlo en toda la jerarquía de vistas, como en 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)
¿Es porque al llamar a SubView () de esta manera, la vista no es parte de la jerarquía de vistas? No lo entiendo ...