SwiftUI에서 팝 오버로 핵심 데이터 엔터티를 저장하면 .environment를 SubView에 다시 전달하지 않고 nilError가 발생합니다.


15

SwiftUI 및 Core Data와 함께 플레이하면서 흥미로운 문제가 발생했습니다. 따라서 상황은 다음과 같습니다.

기본보기 "AppView"와 "SubView"라는 하위보기가 있습니다. NavigationTitleBar에서 더하기 단추를 팝 오버 또는 시트로 클릭하면 SubView보기가 AppView보기에서 열립니다.

@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"오류, 특히 : "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

이 문제를 처음 발견 한 사람은 아니지만 컨텍스트를 매개 변수로 전달하여 해결했습니다. 잘만되면 애플은 곧 고칠 것이다.
— Michael Salmon

1
예상대로 이것은 Swift / SwiftUI 컴파일러의 버그 인 것 같습니다. 그래서 Apple의 Harlan Haskins가 그에 대한 확인을 해주었습니다. bugs.swift.org/browse/SR-11607- 이것이 곧 수정되기를 바랍니다. 빠른 수정의 경우 : .environment (\. managedObjectContext, context)를 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 발전 할만큼 용감
— 아포 스톨 Apostolidis에게

내 문제도 해결되었습니다. 감사합니다.
— P. Ent

1
내 친구! SwiftUI가 왜 이것을 필요로합니까? 환경은 전 세계적으로 액세스해야합니다.
— pulse4life

그러나 왜 필요한가? SwiftUI가 자동으로 만들지 않는 것은 정말 이상합니다 ...
— Loris Foe

현재 버그에 대한 유일한 솔루션이기 때문에 필요합니다. 애플은 분명히 수정 작업을하고있다. SwiftUI는 여전히 매우 새롭다는 것을 기억하십시오.
— stardust4891
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.