Збереження основної сукупності даних у popover у SwiftUI кидає nilError, не передаючи .en Environment в SubView знову


15

Гра з 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")
}

Якщо я спробую зберегти суб'єкт Замовника таким чином, я отримую помилку: "nilError", спеціально: "Невирішена помилка. Помилка помилки = Foundation._GenericObjCError Code = 0" (null) ", [:]" від NSError.

Але після того, як з'ясував, що коли я додаю .environment(\.managedObjectContext, context)в SubView () дзвінок так, SubView().environment(\.managedObjectContext, context)це працює як шарм.

Хтось знає, чому мені потрібно передавати керованийObjectContext вдруге? Я подумав, що мені просто потрібно пройти один раз керованийObjectContext, щоб використовувати його у всій ієрархії перегляду, як у 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 () таким чином, представлення не є частиною ієрархії перегляду? Я цього не розумію ...


1
Я спостерігав таку ж поведінку на iOS 13.1. Xcode 11.1
Arun Patra

Ви не вперше знайшли цю проблему, я вирішив її, передавши контекст як параметр. Сподіваємось, Apple скоро це виправить.
Майкл Лосось

1
Як і очікувалося, це здається помилкою у компіляторі Swift / SwiftUI. Тож Харлан Хаскінс з Apple дав мені підтвердження для цього: bugs.swift.org/browse/SR-11607 - Тож я сподіваюся, що це скоро буде виправлено. Для швидкого виправлення: передача .environment (\. ManagedObjectContext, контекст) до Popover працює на SubView.
lukas_nitaco

Відповіді:


24

ЯК ЦЕ ГРОШУЮТЬ МИ НАГУКИ! Тим більше, що помилки не дають вам абсолютно ніякої інформації щодо виправлення.

Ось виправлення, поки помилка в Xcode не буде усунена:

        .navigationBarItems(trailing:
            Button(action: {
                self.add = true
            }, label: {
                Text("Add Todo List")
            }).sheet(isPresented: $add, content: {
                AddTodoListView().environment(\.managedObjectContext, managedObjectContext)
            })
        )

Просто додайте .environment(\.managedObjectContext, managedObjectContext)до свого вторинного подання (Модальний в цьому прикладі).


8
величезна допомога для всіх нас, досить сміливих, щоб розвиватися в SwiftUI зараз ...
Апостолос Апостолідіс

Вирішив і мою проблему. Дякую.
П. Вступ

1
Мій чувак! Чому SwiftUI робить це необхідним? До навколишнього середовища слід звертатися глобально.
pulse4life

Але навіщо це потрібно? Дійсно дивно, що SwiftUI не робить це автоматично ...
Loris Foe

Це необхідно, тому що це єдине рішення про помилку зараз. Apple, мабуть, працює над виправленням. Пам'ятайте, що SwiftUI все ще дуже новий.
stardust4891
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.