Игра с SwiftUI и Core Data привела меня к любопытной проблеме. Итак, ситуация следующая:
У меня есть основной вид «AppView» и подвид с именем «SubView». Представление SubView будет открыто из представления AppView, если я нажму кнопку «плюс» на панели навигации NavigationTitleBar в виде всплывающего окна или листа.
@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
self.modal.toggle()
}) {
Image(systemName: "plus")
}.popover(isPresented: self.$modal){
SubView()
}
Представление SubView имеет небольшую форму с двумя объектами TextField для добавления имени и фамилии. Входные данные этих двух объектов обрабатываются двумя отдельными свойствами @State. Третий объект в этой форме - простая кнопка, которая должна сохранить имя и фамилию в прикрепленном объекте клиента для 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")
}
Если я пытаюсь сохранить сущность Customer таким способом, я получаю ошибку: «nilError», в частности: «Неразрешенная ошибка Error Domain = Foundation._GenericObjCError Code = 0» (null) », [:]" из NSError.
Но после выяснения, что когда я добавляю .environment(\.managedObjectContext, context)
в вызов SubView () примерно так, SubView().environment(\.managedObjectContext, context)
он работает как шарм.
Кто-нибудь знает, почему мне нужно передать managedObjectContext во второй раз? Я подумал, что мне просто нужно передать managedObjectContext один раз, чтобы использовать его во всей иерархии представления, как в 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)
Это потому, что вызов SubView () таким образом, представление не является частью иерархии представления? Я не понимаю это ...
Ответы:
ВАУ ЭТО ПОБЕЛА МЕНЯ ОРЕХАМИ! Тем более, что ошибки сообщают вам абсолютно никакой информации о том, как исправить.
Вот исправление, пока ошибка в XCode не будет решена:
Просто добавьте
.environment(\.managedObjectContext, managedObjectContext)
к вашему вторичному представлению (модальный, в этом примере).источник