Das Spielen mit SwiftUI und Core Data brachte mich in ein merkwürdiges Problem. Die Situation ist also wie folgt:
Ich habe eine Hauptansicht "AppView" und eine Unteransicht mit dem Namen "SubView". Die SubView-Ansicht wird in der AppView-Ansicht geöffnet, wenn ich in der NavigationTitleBar als Popover oder Blatt auf die Plus-Schaltfläche klicke.
@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
self.modal.toggle()
}) {
Image(systemName: "plus")
}.popover(isPresented: self.$modal){
SubView()
}
Die SubView-Ansicht hat ein kleines Formular mit zwei TextField-Objekten, um einen Vor- und einen Nachnamen hinzuzufügen. Die Eingaben dieser beiden Objekte werden von zwei separaten @ State-Eigenschaften verarbeitet. Das dritte Objekt in diesem Formular ist eine einfache Schaltfläche, mit der Vor- und Nachname für CoreData in einer angehängten Kundenentität gespeichert werden sollen.
...
@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")
}
Wenn ich versuche, die Kundenentität auf diese Weise zu speichern, erhalte ich den Fehler "nilError", insbesondere: "Ungelöster Fehler Fehler Domain = Foundation._GenericObjCError Code = 0" (null) ", [:]" von NSError.
Aber nachdem ich herausgefunden habe, dass, wenn ich .environment(\.managedObjectContext, context)
zum SubView () -Aufruf hinzufüge , soSubView().environment(\.managedObjectContext, context)
wie ein Zauber wirkt.
Weiß jemand, warum ich den manageObjectContext ein zweites Mal übergeben muss? Ich dachte, dass ich den manageObjectContext nur einmal übergeben muss, um ihn in der gesamten Ansichtshierarchie zu verwenden, wie 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)
Liegt es daran, dass die Ansicht nicht Teil der Ansichtshierarchie ist, weil SubView () auf diese Weise aufgerufen wird? Ich verstehe es nicht ...