Giocare con SwiftUI e Core Data mi ha portato a un problema curioso. Quindi la situazione è la seguente:
Ho una vista principale "AppView" e una vista secondaria denominata "SubView". La vista SubView verrà aperta dalla vista AppView se faccio clic sul pulsante più in NavigationTitleBar come popover o foglio.
@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 ha una piccola forma con due oggetti TextField per aggiungere un nome e un cognome. Gli input di questi due oggetti sono gestiti da due proprietà @State separate. Il terzo oggetto in questo modulo è un semplice pulsante, che dovrebbe salvare un nome e cognome in un'entità cliente collegata per 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 provo a salvare l'entità cliente in questo modo, ottengo l'errore: "nilError", in particolare: "Errore non risolto Errore dominio = Foundation._GenericObjCError Code = 0" (null) ", [:]" da NSError.
Ma dopo aver capito, che quando aggiungo .environment(\.managedObjectContext, context)
a SubView () lo chiamo così SubView().environment(\.managedObjectContext, context)
funziona come un incantesimo.
Qualcuno sa, perché ho bisogno di passare una seconda volta a managedObjectContext? Ho pensato che ho solo bisogno di passare una volta il managedObjectContext per usarlo nella gerarchia dell'intera vista, come in 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)
È perché chiamando SubView () in questo modo, la vista non fa parte della gerarchia della vista? Non lo capisco