Brincar com SwiftUI e Core Data me trouxe um problema curioso. Portanto, a situação é a seguinte:
Eu tenho uma vista principal "AppView" e uma sub-vista denominada "SubView". A exibição do SubView será aberta na exibição do AppView se eu clicar no botão de adição no NavigationTitleBar como popover ou planilha.
@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
self.modal.toggle()
}) {
Image(systemName: "plus")
}.popover(isPresented: self.$modal){
SubView()
}
A exibição do SubView possui um pequeno formulário com dois objetos TextField para adicionar um nome e sobrenome. As entradas desses dois objetos são tratadas por duas propriedades @State separadas. O terceiro objeto neste formulário é o botão simples, que deve salvar o nome e o sobrenome em uma Entidade do Cliente anexada 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")
}
Se eu tentar salvar a entidade Cliente dessa maneira, recebo o erro: "nilError", especialmente: "Erro não resolvido Erro Domínio = Foundation._GenericObjCError Code = 0" (null) ", [:]" do NSError.
Mas depois de descobrir, que quando adiciono .environment(\.managedObjectContext, context)
à chamada SubView () assim SubView().environment(\.managedObjectContext, context)
funciona como um encanto.
Alguém sabe, por que eu preciso passar o managedObjectContext uma segunda vez? Eu pensei que só precisava passar o managedObjectContext uma vez para usá-lo em toda a hierarquia de exibição, como no 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)
É porque, ao chamar o SubView () dessa maneira, a exibição não faz parte da hierarquia da exibição? Eu não entendo ...