Gra ze SwiftUI i Core Data przyniosła mi ciekawy problem. Tak więc sytuacja wygląda następująco:
Mam widok główny „AppView” i widok podrzędny o nazwie „SubView”. Widok SubView zostanie otwarty z widoku AppView, jeśli kliknę przycisk plus w NavigationTitleBar jako popover lub arkusz.
@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
self.modal.toggle()
}) {
Image(systemName: "plus")
}.popover(isPresented: self.$modal){
SubView()
}
Widok SubView ma małą formę z dwoma obiektami TextField do dodania imienia i nazwiska. Dane wejściowe tych dwóch obiektów są obsługiwane przez dwie oddzielne właściwości @State. Trzecim obiektem w tym formularzu jest prosty przycisk, który powinien zapisać imię i nazwisko w załączonym podmiocie klienta dla 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")
}
Jeśli spróbuję zapisać encję Klienta w ten sposób, otrzymuję błąd: „nilError”, a zwłaszcza: „Nierozwiązany błąd Błąd Domena = Foundation._GenericObjCError Kod = 0” (null) ”, [:]” z NSError.
Ale po zorientowaniu się, że kiedy dodam .environment(\.managedObjectContext, context)
do wywołania SubView () tak, SubView().environment(\.managedObjectContext, context)
to działa jak urok.
Czy ktoś wie, dlaczego muszę przekazać parametr manageObjectContext po raz drugi? Pomyślałem, że muszę tylko raz przekazać manageObjectContext, aby użyć go w całej hierarchii widoków, jak w 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)
Czy to dlatego, że wywoływanie SubView () w ten sposób, widok nie jest częścią hierarchii widoków? Nie rozumiem tego ...