SwiftUI में पॉपओवर में कोर डेटा यूनिट को सहेजना बिना फिर से पास किए


15

स्विफ्टयूआई और कोर डेटा के साथ प्लेइन ने मुझे एक जिज्ञासु समस्या में ला दिया। तो स्थिति निम्नलिखित है:

मेरे पास एक मुख्य दृश्य "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 दृश्य में दो टेक्स्टफिल्ड ऑब्जेक्ट्स के साथ एक छोटा रूप है, जिसमें एक नाम और एक उपनाम जोड़ना है। इस दो वस्तुओं के इनपुट को दो अलग-अलग @State गुणों द्वारा नियंत्रित किया जाता है। इस रूप में तीसरी वस्तु सरल बटन है, जो कोरडाटा के लिए एक संलग्न ग्राहक इकाई के लिए पहले और उपनाम को बचाना चाहिए।

...
@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 कोड = 0" (null) ", [:]" NSError से।

लेकिन यह पता लगाने के बाद, कि जब मैं .environment(\.managedObjectContext, context)SubView () कॉल में जोड़ता हूं तो SubView().environment(\.managedObjectContext, context)यह एक आकर्षण की तरह काम करता है।

क्या किसी को पता है, मुझे दूसरी बार ManageObjectContext पास करने की आवश्यकता क्यों है? मैंने सोचा, कि मुझे पूरे दृश्य पदानुक्रम में इसका उपयोग करने के लिए एक बार ManageObjectContext पास करना होगा, जैसे 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)

क्या ऐसा इसलिए है क्योंकि सबव्यू () को इस तरह से कॉल करना, दृश्य व्यू पदानुक्रम का हिस्सा नहीं है? मुझे यह समझ में नहीं आता ...


1
मैंने iOS 13.1 पर समान व्यवहार देखा। Xcode 11.1
अरुण पात्रा

आप इस समस्या को खोजने के लिए पहले नहीं हैं, मैंने इसे एक पैरामीटर के रूप में संदर्भ देकर हल किया है। उम्मीद है कि Apple इसे जल्द ही ठीक कर देगा।
माइकल सैल्मन

1
जैसा कि उम्मीद थी कि यह स्विफ्ट / स्विफ्टयूआई के कंपाइलर में एक बग है। इसलिए Apple के Harlan Haskins ने मुझे इसके लिए पुष्टि दी: bugs.swift.org/browse/SR-11607 - इसलिए मुझे उम्मीद है कि यह जल्द ही ठीक हो जाएगा। त्वरित सुधार के लिए: सबवे पॉपओवर कार्यों के लिए पासिंग .environment (\। प्रबंधितObjectContext, संदर्भ)।
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
हम सभी के लिए अपार मदद अभी काफी तेजी से स्विफ्टयूआई में विकसित करने के लिए ...
एपोस्टोलोस एपोस्टोलिडिस

साथ ही मेरी समस्या का समाधान किया। धन्यवाद।
पी। एनटी

1
मेरे दोस्त! SwiftUI इसे आवश्यक क्यों बनाता है? पर्यावरण को विश्व स्तर पर पहुंचना चाहिए।
पल्स 4लाइफ

लेकिन यह क्यों जरूरी है? वास्तव में अजीब है कि स्विफ्टयूआई इसे स्वचालित रूप से नहीं बनाता है ...
लोरिस फो

यह आवश्यक है क्योंकि यह अभी बग का एकमात्र समाधान है। Apple जाहिरा तौर पर एक फिक्स पर काम कर रहा है। याद रखें SwiftUI अभी भी बहुत नई है।
स्टारडस्ट 4891
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.