ApplicationDidBecomeActive को हैंडल करना - "ऐप्स के एक्टिव होने पर व्यू कंट्रोलर कैसे जवाब दे सकता है?"


179

मैं UIApplicationDelegateके साथ मेरी मुख्य AppDelegate.m कक्षा में प्रोटोकॉल, applicationDidBecomeActiveविधि को परिभाषित किया।

मैं एक विधि को कॉल करना चाहता हूं जब एप्लिकेशन पृष्ठभूमि से लौटता है, लेकिन विधि किसी अन्य दृश्य नियंत्रक में है। मैं यह कैसे देख सकता हूं कि वर्तमान में कौन सा व्यू कंट्रोलर applicationDidBecomeActiveविधि में दिखा रहा है और फिर उस कंट्रोलर के लिए एक तरीके से कॉल करें?

जवाबों:


304

आपके आवेदन में कोई भी वर्ग आवेदन में विभिन्न सूचनाओं के लिए "पर्यवेक्षक" बन सकता है। जब आप अपना दृश्य नियंत्रक बनाते हैं (या लोड करते हैं), तो आप इसे एक पर्यवेक्षक के रूप में पंजीकृत करना चाहते हैं UIApplicationDidBecomeActiveNotificationऔर निर्दिष्ट कर सकते हैं कि जब आप उस अधिसूचना को अपने आवेदन में भेजते हैं तो आप किस विधि से कॉल करना चाहते हैं।

[[NSNotificationCenter defaultCenter] addObserver:self
                                         selector:@selector(someMethod:)
                                             name:UIApplicationDidBecomeActiveNotification object:nil];

अपने आप को साफ करने के लिए मत भूलना! जब आपका दृष्टिकोण खत्म हो रहा हो तो पर्यवेक्षक के रूप में खुद को दूर करना याद रखें:

[[NSNotificationCenter defaultCenter] removeObserver:self 
                                                name:UIApplicationDidBecomeActiveNotification
                                              object:nil];

अधिसूचना केंद्र के बारे में अधिक जानकारी ।


अति उत्कृष्ट। का उपयोग करने के बारे में नहीं सोचा था NSNotificationCenter। धन्यवाद!
केल्विन

3
कोड की उस पंक्ति में बस एक टाइपो (लापता 'नाम'): [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector (someMethod :) नाम: UIApplicationDececececéctiveNotification ऑब्जेक्ट: nil];
जॉन्स

3
रीड के उत्तर में जोड़ने के लिए, विधि जिसे कहा जाता है (इस उदाहरण में यह कुछ मैथोड है) को एक NSNotification पैरामीटर को स्वीकार करने की आवश्यकता है। तो कुछ मेथोड के लिए विधि हस्ताक्षर होंगे - (शून्य) someMethod: (NSNotification *) अधिसूचना {// कुछ यहां करें}
हारून

2
@Aaron यह कर सकते हैं, लेकिन यह एक आवश्यकता नहीं है। यह महान अंतर्दृष्टि है, यद्यपि। धन्यवाद!
रीड ऑलसेन

बहुत खुबस! NSTimer इंस्टेंसेस को अमान्य / रीक्रिएट करने का एक शानदार तरीका क्या है, व्यू कंट्रोलर्स / अन्य ऑब्जेक्ट्स में सही है जो उन NSTimers के लिए जिम्मेदार हैं। इसे प्यार करना!
idStar

68

स्विफ्ट 3, 4 समतुल्य:

प्रेक्षक जोड़ना

NotificationCenter.default.addObserver(self,
    selector: #selector(applicationDidBecomeActive),
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

प्रेक्षक को हटा देना

NotificationCenter.default.removeObserver(self,
    name: .UIApplicationDidBecomeActive, // UIApplication.didBecomeActiveNotification for swift 4.2+
    object: nil)

वापस कॉल करें

@objc func applicationDidBecomeActive() {
    // handle event
}

2
मैं यह कहां से कहूंगा?

1
@ user8169082, जहाँ भी आपको सूचनाएँ प्राप्त करने की आवश्यकता होती है, आप एक पर्यवेक्षक जोड़ते हैं। आप इसे viewDidLoadया viewWillAppear:animatedउदाहरण के लिए जोड़ सकते हैं । और आप एक पर्यवेक्षक को हटा सकते हैं जब आपको सूचनाओं की आवश्यकता नहीं होती है, या जब आपके पर्यवेक्षक का उदाहरण
डीइनिट

2
स्विफ्ट 4.2 मैं उपयोग कर रहा हूं: NotificationCenter.default.addObserver (स्वयं, चयनकर्ता: #selector (applicationDidBecomeActive (सूचना :)), नाम: UIApplication.didBomeomeActiveNotification, ऑब्जेक्ट: nil)
ब्रायन

16

स्विफ्ट 2 समतुल्य :

let notificationCenter = NSNotificationCenter.defaultCenter()

// Add observer:
notificationCenter.addObserver(self,
  selector:Selector("applicationWillResignActiveNotification"),
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove observer:
notificationCenter.removeObserver(self,
  name:UIApplicationWillResignActiveNotification,
  object:nil)

// Remove all observer for all notifications:
notificationCenter.removeObserver(self)

// Callback:
func applicationWillResignActiveNotification() {
  // Handle application will resign notification event.
}

removeObserverस्विफ्ट में डालने के लिए सबसे अच्छी जगह : deinitविधि।
एनरिको सुसताओ

आमतौर पर, डेनीट में स्वयं तक पहुंचने की सलाह नहीं दी जाती है; इस बिंदु पर, स्वयं को पूरी तरह से आवंटित किए जाने और
निपटाए

1
तब आप कहां से निकालेंगे?
एनरिको सुसात्यो

2
@EnricoSusatyo आप इसे अनदेखा कर सकते हैं, क्योंकि यह सही नहीं है। ओवरराइडिंग डिनिट ठीक है: "क्योंकि एक उदाहरण को तब तक नहीं निपटाया जाता है जब तक कि उसके डीइन्यूएटलाइज़र को नहीं बुलाया जाता है, एक डीइन्युएलाइज़र उस पर कॉल किए गए इंस्टेंस के सभी गुणों तक पहुंच सकता है और उन गुणों के आधार पर अपने व्यवहार को संशोधित कर सकता है (जैसे कि एक का नाम देखना) फ़ाइल को बंद करने की आवश्यकता है)। "
डिनिट

7

स्विफ्ट 4.2

पर्यवेक्षक जोड़ें-

NotificationCenter.default.addObserver(self, selector: #selector(handleEvent), name: UIApplication.didBecomeActiveNotification, object: nil)

प्रेक्षक निकालें-

NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)

हैंडल इवेंट-

@objc func handleEvent() {
}

5

स्विफ्ट 4 के साथ, Apple एक नए संकलक चेतावनी के माध्यम से सलाह देता है कि हम #selectorइस परिदृश्य में उपयोग से बचें । इसे पूरा करने के लिए एक बहुत ही सुरक्षित तरीका है:

सबसे पहले, एक आलसी संस्करण बनाएं जिसका उपयोग अधिसूचना द्वारा किया जा सकता है:

lazy var didBecomeActive: (Notification) -> Void = { [weak self] _ in
    // Do stuff
} 

यदि आपको वास्तविक अधिसूचना को शामिल करने की आवश्यकता है, तो बस के _साथ बदलें notification

अगला, हमने ऐप सक्रिय होने के लिए अवलोकन करने के लिए अधिसूचना सेट की।

func setupObserver() {
    _ = NotificationCenter.default.addObserver(forName: .UIApplicationDidBecomeActive,
                                               object: nil,
                                               queue:.main,
                                               using: didBecomeActive)
}

यहाँ बड़ा बदलाव यह है कि कॉल करने के बजाय #selector, अब हम ऊपर बनाए गए संस्करण को कॉल करते हैं। यह उन स्थितियों को समाप्त कर सकता है जहां आपको अमान्य चयनकर्ता क्रैश मिलते हैं।

अंत में, हम पर्यवेक्षक को हटा देते हैं।

func removeObserver() {
    NotificationCenter.default.removeObserver(self, name: .UIApplicationDidBecomeActive, object: nil)
}

1
#selector@objcस्विफ्ट 4 में एक विशेषता के रूप में घोषित एक विधि कह सकते हैं
AnBisw

1
इसका उपयोग करना गलत है removeObserver(selfक्योंकि पर्यवेक्षक जोड़ते समय स्वयं को असाइन नहीं किया गया था। let observer = NotificationCenter.default.addObserverतब आपको चाहिएremoveObserver(observer
यान कल्बस्का

धन्यवाद @CodeBender मुझे अभी तक उस फ़ंक्शन का पता नहीं था और यह (अंत में) हटा देता है @objc। हालाँकि जब मैं इसे आज़माता हूँ तो मुझे कंसोल में एक चेतावनी मिलती है (Xcode 11.3.1 (11C504), स्विफ्ट 13.3): पृष्ठभूमि समाप्त नहीं हो सकती: पहचानकर्ता के साथ कोई पृष्ठभूमि कार्य मौजूद नहीं है। यहां तक ​​कि अगर मैं पर्यवेक्षक को NSObjectProtocol के रूप में एक चर में बचाता हूं।
पामे

अगर मैं @objcवेरिएंट का उपयोग करता हूं तो मुझे कभी-कभी चेतावनी भी मिलती है ।
पामे

3

स्विफ्ट 5

fileprivate  func addObservers() {
      NotificationCenter.default.addObserver(self,
                                             selector: #selector(applicationDidBecomeActive),
                                             name: UIApplication.didBecomeActiveNotification,
                                             object: nil)
    }

fileprivate  func removeObservers() {
        NotificationCenter.default.removeObserver(self, name: UIApplication.didBecomeActiveNotification, object: nil)
    }

@objc fileprivate func applicationDidBecomeActive() {
// here do your work
    }

0

कम्बाइन रास्ता:

import Combine

var cancellables = Set<AnyCancellable>()
NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)
    .sink { notification in
            // do stuff
    }.store(in: &cancellables)
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.