Menyimpan entitas data inti dalam popover di SwiftUI melempar nilError tanpa melewatkan .environment ke SubView lagi

15

Bermain dengan SwiftUI dan Core Data membawa saya ke masalah yang aneh. Jadi situasinya adalah sebagai berikut:

Saya memiliki tampilan utama "AppView" dan tampilan sub bernama "SubView". Tampilan SubView akan dibuka dari tampilan AppView jika saya mengklik tombol plus di NavigationTitleBar sebagai popover atau sheet.

@Environment(\.managedObjectContext) var managedObjectContext
@State private var modal: Bool = false
...
Button(action: {
        self.modal.toggle()
      }) {
        Image(systemName: "plus")
      }.popover(isPresented: self.$modal){
        SubView()
      }

Tampilan SubView memiliki bentuk kecil dengan dua objek TextField untuk menambahkan nama depan dan nama keluarga. Input dari dua objek ini ditangani oleh dua properti @State yang terpisah. Objek ketiga dalam formulir ini adalah tombol sederhana, yang harus menyimpan nama depan dan nama belakang ke Entitas Pelanggan yang dilampirkan untuk 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")
}

Jika saya mencoba menyelamatkan entitas Pelanggan dengan cara ini, saya mendapatkan kesalahan: "nilError", khususnya: "Kesalahan yang belum terselesaikan Domain Kesalahan = Yayasan._GenericObjCEKoreksi Kode = 0" (null) ", [:]" dari NSError.

Tapi setelah mencari tahu, itu ketika saya menambahkan .environment(\.managedObjectContext, context)ke panggilan SubView () seperti ituSubView().environment(\.managedObjectContext, context) itu berfungsi seperti pesona.

Adakah yang tahu, mengapa saya harus meneruskan managedObjectContext untuk kedua kalinya? Saya pikir, bahwa saya hanya perlu melewatkan managedObjectContext satu kali untuk menggunakannya dalam hierarki tampilan keseluruhan, seperti di 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)

Apakah karena memanggil SubView () dengan cara ini, tampilan bukan bagian dari hierarki tampilan? Saya tidak mengerti ...

lukas_nitaco
sumber
1
Saya mengamati perilaku yang sama di iOS 13.1. Xcode 11.1
Arun Patra
Anda bukan orang pertama yang menemukan masalah ini, saya menyelesaikannya dengan mengirimkan konteks sebagai parameter. Semoga Apple akan segera memperbaikinya.
Michael Salmon
1
Seperti yang diharapkan ini tampaknya menjadi bug di Compiler of Swift / SwiftUI. Jadi Harlan Haskins dari Apple memberi saya konfirmasi untuk itu: bugs.swift.org/browse/SR-11607 - Jadi saya harap ini akan segera diperbaiki. Untuk perbaikan cepat: Melewati .environment (\. ManagedObjectContext, konteks) ke karya popover SubView.
lukas_nitaco

Jawaban:

24

WOW DRIDE INI SAYA Kacang-kacangan! Terutama karena kesalahan memberitahu Anda sama sekali tidak ada informasi tentang cara memperbaikinya.

Ini adalah perbaikan sampai bug di Xcode teratasi:

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

Tambahkan saja .environment(\.managedObjectContext, managedObjectContext)ke tampilan sekunder Anda (Modal, dalam contoh ini).

kdion4891
sumber
8
bantuan besar bagi kita semua yang cukup berani untuk berkembang di SwiftUI sekarang ...
Apostolos Apostolidis
Memecahkan masalah saya juga. Terima kasih.
P. Ent
1
Bung saya! Mengapa SwiftUI membuat ini perlu? Lingkungan harus diakses secara global.
pulse4life
Tetapi mengapa itu perlu? Sangat aneh SwiftUI tidak membuatnya secara otomatis ...
Loris Foe
Itu perlu karena itu adalah satu-satunya solusi untuk bug saat ini. Apple tampaknya sedang memperbaiki. Ingat SwiftUI masih sangat baru.
stardust4891