SwiftUIのポップオーバーでコアデータエンティティを保存すると、.environmentをSubViewに再度渡さずにnilErrorがスローされる


15

SwiftUIとCore DataでPlayinを実行すると、興味深い問題が発生しました。したがって、状況は次のとおりです。

メインビュー「AppView」と「SubView」というサブビューがあります。NavigationTitleBarのプラスボタンをポップオーバーまたはシートとしてクリックすると、AppViewビューからSubViewビューが開きます。

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

SubViewビューには、姓と名を追加する2つのTextFieldオブジェクトを持つ小さなフォームがあります。この2つのオブジェクトの入力は、2つの個別の@Stateプロパティによって処理されます。このフォームの3番目のオブジェクトは単純なボタンで、CoreDataのアタッチされたCustomerエンティティに姓名を保存する必要があります。

...
@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」というエラーが発生します。特に、NSErrorから「Unresolved error Error Domain = Foundation._GenericObjCError Code = 0 "(null)"、[:] "というエラーが発生します。

しかし、それを理解した後.environment(\.managedObjectContext, context)、SubView()呼び出しに次のように追加すると、SubView().environment(\.managedObjectContext, context)魅力のように機能します。

誰か知っていますか、managedObjectContextをもう一度渡す必要があるのはなぜですか?SceneDelegate.swiftのように、ビュー階層全体でそれを使用するには、managedObjectContextを一度だけ渡す必要があると思いました。

    // 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はすぐに修正するでしょう。
Michael Salmon、

1
予想通り、これはSwift / SwiftUIのコンパイラのバグのようです。そのため、アップルのHarlan Haskinsから確認が得られました:bugs.swift.org/browse/SR-11607-すぐに修正されることを願っています。クイックフィックスの場合:SubViewポップオーバーに.environment(\。managedObjectContext、context)を渡すと機能します。
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で開発するのに十分な勇気のある私たち全員への計り知れない助け...
Apostolos Apostolidis

私の問題も解決しました。ありがとうございました。
P. Ent

1
私の男!なぜSwiftUIはこれを必要とするのですか?環境にはグローバルにアクセスする必要があります。
pulse4life

しかし、なぜそれが必要なのでしょうか?SwiftUIが自動的に作成しないことは本当に奇妙です...
Loris Foe

それは今のところバグの唯一の解決策なので必要です。Appleは明らかに修正に取り組んでいる。SwiftUIはまだ非常に新しいことを覚えておいてください。
stardust4891
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.