UIApplication.registerForRemoteNotifications () को केवल मुख्य धागे से बुलाया जाना चाहिए


81

पुश (दूरस्थ) अधिसूचना के लिए पंजीकरण करते समय Xcode 9 (iOS 11) मुझे एक त्रुटि / चेतावनी दिखा रहा है।

यहाँ त्रुटि संदेश है

यहाँ छवि विवरण दर्ज करें

और यहाँ कोड है, मैंने कोशिश की है:

let center  = UNUserNotificationCenter.current()
center.delegate = self
center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
        if error == nil{
              UIApplication.shared.registerForRemoteNotifications()
        }
 }

त्रुटि / चेतावनी पंक्ति:

UIApplication.sared.registerForRemoteNotifications ()

इसका समाधान कैसे करें?


2
जैसा कि त्रुटि संदेश में कहा गया है, आपको कॉल को UIApplication.shared.registerForRemoteNotifications()मुख्य धागे में लपेटना होगा । :) Google को इसे मुख्य सूत्र में कैसे कॉल करें ...
ड्यूएन-होआ

@ क्यों आपको मेनहेड से ऐसा करने की आवश्यकता होगी? यह यूआई से संबंधित नहीं है ... या क्या यह इसलिए है क्योंकि इसमें कुछ सेकंड बाद होने की क्षमता है और यह अप्रत्याशित व्यवहार का कारण बन सकता है?
हनी

मुझे भी यही भ्रम है, कि स्विफ्ट 4 मुझे यह त्रुटि संकेतक क्यों दिखा रहा है ...
क्रुनाल

@Sulthan UIApplication.shared.registerForRemoteNotifications()UI संबंधित नहीं है (जब आप चुप सूचना के लिए टोकन प्राप्त करते हैं तो आप उपयोगकर्ताओं को संकेत नहीं देते हैं)। तो जिस लाइन पर त्रुटि दिखाई दे रही है वह भ्रामक है। हालाँकि बैज, अलर्ट, साउंड के लिए पंजीकरण करना UI से संबंधित है और इसे मुख्य धागे से करना बेहतर है ... इसलिए कुल मिलाकर पूरे ब्लॉक को center.requestAuthorization(options:...मुख्य धागे से किया जाना चाहिए ... यह समझ में आता है
हनी

मुझे एक समस्या थी जो इसका विस्तार करती है जो यहां पाई जा सकती है । मेरे पास इस प्रश्न के साथ-साथ अन्य में भी त्रुटि संदेश था।
जोशोर

जवाबों:


143

में swift4

आप इस समस्या को हल कर सकते हैं

DispatchQueue.main.async {
  UIApplication.shared.registerForRemoteNotifications()
}

आशा है कि यह मदद करेगा ...


और भी सरल, बंद करने की कोई आवश्यकता नहीं है:DispatchQueue.main.async(execute: UIApplication.shared.registerForRemoteNotifications())
नथन

@ नथन मुझे लगता है कि आपको बंद करने की आवश्यकता है। मुझे Cannot invoke 'async' with an argument list of type '(execute: Void)'आपके उदाहरण का उपयोग करने में त्रुटि हुई।
bvpb

4
क्षमा करें, टाइपो DispatchQueue.main.async(execute: UIApplication.shared.registerForRemoteNotifications):। executeउम्मीद है एक समारोह / प्रकार के बंद होने () -> Voidइतना registerForRemoteNotificationsकाम करता है
नाथन

1
कैसे उद्देश्य सी में लिखने के लिए।
पूजा श्रीवास्तव

5
@ पूजा पूजा श्रीवास्तवdispatch_async(dispatch_get_main_queue(), ^{ //Do stuff });
नवघनेश

46

ऑब्जेक्टिव सी के लिए, नीचे दिया गया कोड काम करता है

    dispatch_async(dispatch_get_main_queue(), ^{
        [[UIApplication sharedApplication] registerForRemoteNotifications];
    });

37

टीएल; डीआर:
सभी यूआई जोड़तोड़ समस्याओं से बचने के लिए मुख्य थ्रेड में किया जाना चाहिए। यदि ऐसा करने में विफल रहा, तो मेन थ्रेड चेकर (XCode 9 में नई शुरू की गई डिबगिंग सुविधा) रनटाइम पर मुद्दों का उत्पादन करेगा। इसलिए ग्लिस और रनटाइम चेतावनियों से बचने के लिए अपने कोड को मेन थ्रेड ब्लॉक में लपेटें।

DispatchQueue.main.async {
    UIApplication.shared.registerForRemoteNotifications()
}

Ver से पहले Xcode में रिलीज़ होती है। 9, मुख्य धागे से संबंधित चेतावनियाँ सांत्वना क्षेत्र में पाठकीय रूप से छपी होंगी। वैसे भी, आप वैकल्पिक रूप से एडिट स्कीम में डायग्नोस्टिक सेटिंग्स में मेन थ्रेड चेकर को डिसेबल नहीं कर सकते हैं ।


स्पष्टीकरण:

Apple ने UCit के लिए रनटाइम पर मुद्दों की जाँच के लिए XCode 9 में एक नया डिबगिंग विकल्प पेश किया और यूआई के अन्य तत्वों में हेरफेर किया। यदि मेन थ्रेड ब्लॉक के बिना रनटाइम पर यूआईआईटी एपीआई से यूआई तत्वों में कोई बदलाव होता है, तो यह यूआई ग्लिच और क्रैश का कारण होने की संभावना है। मुख्य थ्रेड परीक्षक कार्यावधि में उन मुद्दों को पकड़ने के लिए डिफ़ॉल्ट रूप से सक्षम है। आप नीचे दी गई तरह एडिट स्कीम विंडो में मेन थ्रेड चेकर को निष्क्रिय कर सकते हैं , हालाँकि ऐसा करने की वास्तव में सिफारिश नहीं की गई है:

मुख्य थ्रेड चेकर को अक्षम करें

यदि आपके पास कोई पुराना एसडीके या फ्रेमवर्क है, तो Xcode 9 को अपडेट करते समय, आपको इस चेतावनी का सामना करना पड़ सकता है क्योंकि कुछ UIKit विधि कॉल मेन थ्रेड में लपेटी नहीं गई होंगी। उन्हें नवीनतम संस्करण में अद्यतन करने से समस्या ठीक हो जाएगी (यदि डेवलपर को इसके बारे में पता है और इसे ठीक कर दिया गया है)।

XCode 9 बीटा रिलीज़ नोट से उद्धरण:

  • Xcode 9 में नया - मुख्य थ्रेड चेकर।
    • पृष्ठभूमि थ्रेड से UI API के दुरुपयोग का पता लगाने में सक्षम करें
    • AppKit, UIKit और WebKit विधि कॉल का पता लगाता है जो मुख्य धागे पर नहीं बनाई गई हैं।
    • डिबगिंग के दौरान स्वचालित रूप से सक्षम है, और योजना संपादक के नैदानिक ​​टैब में अक्षम किया जा सकता है।
    • मुख्य थ्रेड चेकर स्विफ्ट और सी भाषाओं के साथ काम करता है।

1
उत्सुक आप इस Xcode 9 नई सेटिंग्स को इतनी जल्दी कैसे सीख गए? अभी तक कोई WWDC वीडियो नहीं हैं!
हनी

4
@ हनी जारी नोटों में आमतौर पर सभी आवश्यक बदलाव होते हैं :)
सुल्तान

4
@ हनी कुछ लोगों ने रिलीज नोट्स और प्रलेखन ;-)
vadian

1
@Honey गंभीरता से, यह हमेशा (Xcode) रिलीज़ नोट्स पढ़ने के लिए लायक है।
विंध्य

2
@BadhanGanesh (मैं नीच नहीं और न ही उत्थान किया) यदि ऐसा नहीं है तो आप जो चाहते हैं तो उसे फिर से लिखें ... क्योंकि यह किसी को कह रहा है कि मुझे समस्या है एक्स ... और फिर आप उत्तर दे रहे हैं कि आप वाई कर सकते हैं .... अच्छी तरह से ओपी जवाब की तलाश है। अगर यह सिर्फ एक स्पष्टीकरण से स्पष्ट है कि यह जवाब नहीं है
हनी

6

त्रुटि संदेश बहुत स्पष्ट है: registerForRemoteNotificationsमुख्य थ्रेड के लिए प्रेषण ।

मैं grantedपैरामीटर का उपयोग करता हूं और errorतदनुसार संभालता हूं

center.requestAuthorization(options: [.sound, .alert, .badge]) { (granted, error) in
        if granted {
              DispatchQueue.main.async {
                  UIApplication.shared.registerForRemoteNotifications()
              }
        } else {
           print(error!)
           // handle the error
        }
}

3

यह स्विफ्ट 4.0 में करने का सही तरीका भी है

UNUserNotificationCenter.current().delegate = self
        UNUserNotificationCenter.current().requestAuthorization(options: [.alert,.sound,.badge], completionHandler: {(granted,error) in
            if granted{
                DispatchQueue.main.async {
                    application.registerForRemoteNotifications()
                }
            }
        })

1

आशा है कि यह मदद करेगा

DispatchQueue.main.async(execute: {
  UIApplication.shared.registerForRemoteNotifications()
})

1

इसी से मेरा काम बना है। उपरोक्त टिप्पणी में @ Mason11987 के सौजन्य से।

DispatchQueue.main.async() { code }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.