Збереження основної сукупності даних у 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.