पता लगाएँ कि क्या एप्लिकेशन को एक धक्का अधिसूचना से लॉन्च / खोला गया था


172

क्या यह जानना संभव है कि क्या ऐप को धक्का अधिसूचना से लॉन्च / खोला गया था?

मुझे लगता है कि लॉन्चिंग इवेंट यहां पकड़ा जा सकता है:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {

    if (launchOptions != nil) {
         // Launched from push notification
         NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];

    }
}

हालाँकि, मैं यह कैसे पता लगा सकता हूं कि जब ऐप पृष्ठभूमि में था, तो इसे एक धक्का अधिसूचना से खोला गया था?


6
यह एक पुरानी, ​​लेकिन बहुत उपयोगी पोस्ट है। दुर्भाग्यवश शीर्ष उत्तर वास्तविक समस्या का समाधान नहीं करते हैं (जैसा कि टिप्पणी से पता चलता है)। कृपया नए उत्तर को 'स्वीकृत' के रूप में चिह्नित करने पर विचार करें क्योंकि वर्तमान में यह पूरा नहीं है।
मोबाइलवीट

1
इस प्रश्न के 100k + विचार हैं लेकिन चयनित उत्तर गलत या पूर्ण है। आगंतुकों के लिए, आधुनिक समाधान खोजने के लिए वोट के बजाय सक्रिय द्वारा छंटाई पर विचार करें।
अल्बर्ट रेनशॉ

जवाबों:


187

यह कोड देखें:

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground  )
    {
         //opened from a push notification when the app was on background
    }
}

के समान

-(void)application:(UIApplication *)application didReceiveLocalNotification (UILocalNotification *)notification

19
@ManuelM। यह एक अच्छा जवाब है कि यह दिखाता है कि कैसे पता लगाया जाए कि जब पृष्ठभूमि में किसी ऐप को पुश अधिसूचना से अग्रभूमि में लाया जाता है। जब एप्लिकेशन नहीं चल रहा हो, तो आपको नीचे दिए गए एम। ओथमैन के उत्तर की आवश्यकता होगी।
OpenUserX03

6
मुझे आवेदन करने के लिए कॉल मिल रहा है: didReceiveRemoteNotification: नोटिफिकेशन को टैप करने के बाद इस बात की परवाह किए बिना कि ऐप सिर्फ बैकग्राउंड में है या बिल्कुल भी नहीं चल रहा है, इसलिए यह उत्तर पूरी तरह से मेरी जरूरतों के अनुरूप है। IOS 7 और 8
Newtz

16
कुछ अन्य लोगों की तरह, यह "एक पुश अधिसूचना से लॉन्च / खोला" का पता नहीं लगाता है। यह कहा जाता है जब अधिसूचना प्राप्त होती है, तब नहीं जब इसे खोला जाता है। इसलिए यदि आपको bg में एक सूचना मिली है, लेकिन ऐप को खोलने के लिए ऐप आइकन पर टैप किया गया है, तो आपके पास यहां मौजूद कोड अभी भी चलने वाला है, और आप एक पेज खोल सकते हैं, जिसे उपयोगकर्ता खोलने का इरादा नहीं करता है।
बाओ लेई

4
@ManuelM। यह विधि यह नहीं बताती है कि यदि पृष्ठभूमि मोड - दूरस्थ अधिसूचना की जाँच की जाती है, तो ऐप को अधिसूचना केंद्र बनाम ऐप आइकन के माध्यम से खोला गया था या नहीं। यह अनियंत्रित होने पर करता है। मैंने इस पोस्ट में अंतर का दस्तावेजीकरण किया है: stackoverflow.com/questions/32061897/…
बाओ लेई

2
पुष्टि की कि यह Google क्लाउड मैसेजिंग के साथ काम करता है।
CularBytes

127

देर से लेकिन शायद उपयोगी है

जब ऐप नहीं चल रहा हो

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

कहा जाता है ..

जहाँ आपको पुश सूचना के लिए जाँच करने की आवश्यकता है

NSDictionary *notification = [launchOptions objectForKey:UIApplicationLaunchOptionsRemoteNotificationKey];
if (notification) {
    NSLog(@"app recieved notification from remote%@",notification);
    [self application:application didReceiveRemoteNotification:notification];
} else {
    NSLog(@"app did not recieve notification");
}

2
ध्यान दें कि उपरोक्त स्निपेट में, नोटिफिकेशन को (UILocalNotification *) घोषित नहीं किया जाना चाहिए, लेकिन (NS ढलान *)
cosmix

1
इस तरह आप देख सकते हैं कि ऐप के लिए कोई नोटिफिकेशन था, जबकि नहीं चल रहा है! सवाल था कि अगर ऐप को नोटिफिकेशन से खोला जाए तो कैसे पता लगाया जाए। इस मामले में didReceiveRemoteNotification कहा जाता है, भले ही ऐप बिल्कुल भी नहीं चल रहा हो। - मुझे आपका उत्तर पसंद है, क्योंकि यह कई मामलों के लिए महत्वपूर्ण है, लेकिन प्रश्न का सही उत्तर नहीं है।
एक्सल ज़हेन

क्या आपका उत्तर और यह उत्तर दोनों एक ही काम कर रहे हैं?
हनी

38

हमारे पास जो समस्या थी वह ऐप लॉन्च होने के बाद दृश्य को सही ढंग से अपडेट करने में थी। यहाँ जीवन चक्र विधियों के जटिल क्रम हैं जो भ्रामक हैं।

जीवनचक्र की विधियाँ

IOS 10 के लिए हमारे परीक्षण में विभिन्न मामलों के लिए जीवन चक्र विधियों के निम्नलिखित अनुक्रमों का पता चला:

DELEGATE METHODS CALLED WHEN OPENING APP  

Opening app when system killed or user killed  
    didFinishLaunchingWithOptions  
    applicationDidBecomeActive    

Opening app when backgrounded  
    applicationWillEnterForeground  
    applicationDidBecomeActive  

DELEGATE METHODS WHEN OPENING PUSH

Opening push when system killed
    [receiving push causes didFinishLaunchingWithOptions (with options) and didReceiveRemoteNotification:background]
    applicationWillEnterForeground
    didReceiveRemoteNotification:inactive
    applicationDidBecomeActive

Opening push when user killed
    didFinishLaunchingWithOptions (with options)
    didReceiveRemoteNotification:inactive [only completionHandler version]
    applicationDidBecomeActive

Opening push when backgrounded
    [receiving push causes didReceiveRemoteNotification:background]
    applicationWillEnterForeground
    didReceiveRemoteNotification:inactive
    applicationDidBecomeActive

समस्या

ठीक है, तो अब हमें इसकी आवश्यकता है:

  1. यह निर्धारित करें कि उपयोगकर्ता पुश से ऐप खोल रहा है या नहीं
  2. पुश स्थिति के आधार पर दृश्य को अपडेट करें
  3. स्थिति को साफ करें ताकि बाद में खुलने वाले उपयोगकर्ता को उसी स्थिति में वापस न करें।

मुश्किल बिट यह है कि दृश्य को अपडेट करना तब होता है जब एप्लिकेशन वास्तव में सक्रिय हो जाता है, जो सभी मामलों में एक ही जीवनचक्र विधि है।

हमारे समाधान का स्केच

यहाँ हमारे समाधान के मुख्य घटक हैं:

  1. notificationUserInfoAppDelegate पर एक इंस्टेंस वेरिएबल स्टोर करें ।
  2. notificationUserInfo = nilदोनों में सेट applicationWillEnterForegroundऔर didFinishLaunchingWithOptions
  3. सेट notificationUserInfo = userInfoमेंdidReceiveRemoteNotification:inactive
  4. applicationDidBecomeActiveहमेशा एक कस्टम विधि से कॉल करें openViewFromNotificationऔर पास करें self.notificationUserInfo। यदि self.notificationUserInfoशून्य है, तो जल्दी वापस लौटें, अन्यथा अंदर मिली अधिसूचना स्थिति के आधार पर दृश्य खोलें self.notificationUserInfo

व्याख्या

जब एक धक्का से खोलना didFinishLaunchingWithOptionsया applicationWillEnterForegroundहमेशा तुरंत पहले बुलाया जाता है didReceiveRemoteNotification:inactive, तो हम पहले इन तरीकों में सूचना को रीसेट करते हैं ताकि कोई बासी स्थिति न हो। फिर, अगर didReceiveRemoteNotification:inactiveकहा जाता है कि हम जानते हैं कि हम एक धक्का से खोल रहे हैं तो हम सेट करते हैं self.notificationUserInfoजो तब applicationDidBecomeActiveउपयोगकर्ता को सही दृश्य के लिए अग्रेषित करने के लिए उठाया जाता है ।

एक अंतिम मामला यह है कि यदि उपयोगकर्ता के पास ऐप स्विचर के भीतर खुला है (यानी ऐप होमग्राउंड में रहते हुए होम बटन को डबल टैप करके) और फिर एक पुश नोटिफिकेशन प्राप्त करता है। इस मामले में केवल didReceiveRemoteNotification:inactiveकॉल किया जाता है, और न ही WillEnterForeground और न हीFinishLaunching कहा जाता है तो आपको उस मामले को संभालने के लिए कुछ विशेष राज्य की आवश्यकता होती है।

उम्मीद है की यह मदद करेगा।


अंत में कुछ है कि काम करता है, धन्यवाद! मैं एक झंडा बनाना चाहता था "appResuming" और स्क्रीन को उन receiveतरीकों से खोलें जब ऐप स्थिति सक्रिय हो या ऐप फिर से शुरू हो रहा हो। जब ऐप अभी भी निष्क्रिय है, तो बदलते वीसी के साथ समस्याएँ हो सकती हैं। आपका समाधान बहुत अच्छा लग रहा है, जब तक कि ऐप्पल जीवन चक्र को फिर से नहीं बदलता।
शेल्फ़

IOS 9 के बारे में क्या, जीवनचक्र के तरीके उसी तरह से और क्रमबद्ध हैं? मेरे पास पहले से कोई iOS 9 डिवाइस नहीं है इसलिए मैं इसे ठीक से जांच नहीं सकता।
शेल

2
ऐप स्विचर को छोड़कर दो और एज केस हैं। 1) जब सूचना केंद्र को ऊपर से खींचा जाता है और एप्लिकेशन को ओवरले किया जाता है 2) जब वाईफाई / बीटी / आदि के साथ iOS का पैनल नीचे से खींचा जाता है और ऐप को ओवरले करता है। इन तीनों मामलों में सिर्फ applicationWillResignActiveबुलाया जाता है और फिर द applicationDidBecomeActive। इसलिए applicationWillResignActiveकहा जाता है के बाद प्राप्त अधिसूचना को बचाने के लिए जब तक एक applicationDidEnterBackgroundया applicationDidBecomeActiveकहा जाता है नहीं है।
कवच

इन मामलों को जोड़ने के लिए शुक्रिया @shelll। यह हमेशा अधिक जटिल हो जाता है! मुझे iOS9 के बारे में निश्चित नहीं है। मैं कहूंगा कि यह मान लेना सुरक्षित है कि वे एक ही हैं, लेकिन कौन जानता है।
एरिक कोनर

बिलकुल चौकन्ना। मैं आज iOS 11 बीटा 9 का परीक्षण कर रहा था और पाया कि उस मामले में जहां आप अपने ऐप को अग्रभूमि में रखते हैं, फोन को लॉक करते हैं, और फिर लॉक स्क्रीन से एक पुश नोटिफिकेशन का चयन करते हैं, यह कॉल कर रहा है doReceiveRemoteNotification: कॉलिंग बैकग्राउंड फॉर एप्लीकेशनविलीइंटरफ़ॉरग्राउंड हम iOS 10 पर क्या देख रहे हैं, जहां यह applicationWillEnterForeground और फिर didReceiveRemoteNotification कहता है: निष्क्रिय - तो यह एक किनारे का मामला है जो अभी तक कवर नहीं किया गया है। मेरी राय में यह आईओएस कोड में एक बग है, लेकिन यह देखते हुए कि iOS 11 रिलीज कितना करीब है, इसके बारे में पता होना चाहिए।
रॉय

24

यह एक अच्छी तरह से पहना हुआ पद है ... लेकिन यह अभी भी समस्या का एक वास्तविक समाधान याद कर रहा है (जैसा कि विभिन्न टिप्पणियों में बताया गया है)।

मूल प्रश्न यह पता लगाने के बारे में है कि ऐप को एक पुश अधिसूचना से कब लॉन्च / खोला गया था , उदाहरण के लिए उपयोगकर्ता अधिसूचना पर टैप करता है। कोई भी उत्तर वास्तव में इस मामले को कवर नहीं करता है।

नोटिफिकेशन आने पर इसका कारण कॉल फ्लो देखा जा सकता है, application:didReceiveRemoteNotification...

अधिसूचना प्राप्त होने पर फिर से बुलाया जाता है और जब उपयोगकर्ता द्वारा अधिसूचना का दोहन किया जाता है। इस वजह से, आप केवल यह नहीं देख सकते UIApplicationStateकि उपयोगकर्ता ने इसे टैप किया था।

इसके अतिरिक्त, आपको अब ऐप की 'कोल्ड स्टार्ट' की स्थिति को संभालने की आवश्यकता नहीं है application:didFinishLaunchingWithOptions...जैसा application:didReceiveRemoteNotification...कि iOS 9+ (शायद 8 के रूप में अच्छी तरह से) लॉन्च करने के बाद फिर से कहा जाता है।

तो, आप कैसे बता सकते हैं कि उपयोगकर्ता नल ने घटनाओं की श्रृंखला शुरू की? मेरा समाधान उस समय को चिह्नित करना है जिस पर एप्लिकेशन पृष्ठभूमि से बाहर आना शुरू करता है या ठंड शुरू होता है और फिर उस समय की जांच करता है application:didReceiveRemoteNotification...। यदि यह 0.1 से कम है, तो आप सुनिश्चित कर सकते हैं कि टैप ने स्टार्टअप को ट्रिगर किया।

स्विफ्ट 2.x

class AppDelegate: UIResponder, UIApplicationDelegate {

  var wakeTime : NSDate = NSDate()        // when did our application wake up most recently?

  func applicationWillEnterForeground(application: UIApplication) {    
    // time stamp the entering of foreground so we can tell how we got here
    wakeTime = NSDate()
  }

  func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
    // ensure the userInfo dictionary has the data you expect
    if let type = userInfo["type"] as? String where type == "status" {
      // IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
      if application.applicationState != UIApplicationState.Background && NSDate().timeIntervalSinceDate(wakeTime) < 0.1 {
        // User Tap on notification Started the App
      }
      else {
        // DO stuff here if you ONLY want it to happen when the push arrives
      }
      completionHandler(.NewData)
    }
    else {
      completionHandler(.NoData)
    }
  }
}

स्विफ्ट 3

class AppDelegate: UIResponder, UIApplicationDelegate {

    var wakeTime : Date = Date()        // when did our application wake up most recently?

    func applicationWillEnterForeground(_ application: UIApplication) {
      // time stamp the entering of foreground so we can tell how we got here
      wakeTime = Date()
    }

  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

      // ensure the userInfo dictionary has the data you expect
      if let type = userInfo["type"] as? String, type == "status" {
        // IF the wakeTime is less than 1/10 of a second, then we got here by tapping a notification
        if application.applicationState != UIApplicationState.background && Date().timeIntervalSince(wakeTime) < 0.1 {
          // User Tap on notification Started the App
        }
        else {
          // DO stuff here if you ONLY want it to happen when the push arrives
        }
        completionHandler(.newData)
      }
      else {
        completionHandler(.noData)
      }
    }
}

मैंने iOS 9+ पर दोनों मामलों (पृष्ठभूमि में ऐप, ऐप नहीं चल रहा) के लिए यह परीक्षण किया है और यह एक आकर्षण की तरह काम करता है। 0.1s बहुत रूढ़िवादी है, वास्तविक मान ~ 0.002s है, इसलिए 0.01 ठीक है।


1
यह एकमात्र कार्यशील समाधान प्रतीत होता है जो वास्तव में अधिसूचना को टैप करने और ऐप पर स्टेटस-बार खोलने के बीच अंतर करता है।
liviucmg

4
यह StackOverflow के सभी से एकमात्र कार्यशील समाधान है। केवल एक चीज जो मैं जोड़ना चाहूंगा, वह यह है कि जब आप iOS 10 और उच्चतर का समर्थन करते हैं, तो आप बस UNNotificationCenterएपीआई, विशेष रूप से UNNotificationCenterDelegate तरीकों का उपयोग कर सकते हैं । userNotificationCenter(UNUserNotificationCenter, didReceive: UNNotificationResponse, withCompletionHandler: @escaping () -> Void) जब उपयोगकर्ता वास्तव में अधिसूचना पर टैप कर चुके हों, तब ही एपीआई कॉल फंक विधि होती है।
डेनहाइडलेस

यह स्विफ्ट 3 के लिए कैसा दिखता है?
जोहान Josterreicher

एक ऐप निष्क्रिय अवस्था में होने पर भी काम नहीं करता है (उपयोगकर्ता सूचना केंद्र को स्वाइप करता है या नियंत्रण केंद्र को स्वाइप करता है) और एक अधिसूचना प्राप्त करता है। जब उपयोगकर्ता नोटिफ़िकेशन पर टैप करता है तो ऐप को applicationWillEnterForeground कॉल प्राप्त नहीं होता है , परिणामस्वरूप समाधान टैप का पता लगाने में विफल रहता है।
देवगंता १18 ’

@DevGansta जब आप के रूप में अपने वर्ग को जोड़ने UNUserNotificationCenter.current().delegateमें application:didFinishLaunchingWithOptions, अनुप्रयोग कॉल करेंगे userNotificationCenter(didReceive response)मामला आप वर्णित में नल के बाद
डोरियन रॉय

22

जब एप्लिकेशन समाप्त हो जाता है, और उपयोगकर्ता पुश अधिसूचना पर टैप करता है

public func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
   if launchOptions?[UIApplicationLaunchOptionsKey.remoteNotification] != nil {
      print("from push")
    }
}

जब एप्लिकेशन पृष्ठभूमि में होता है, और उपयोगकर्ता पुश नोटिफिकेशन पर टैप करता है

यदि उपयोगकर्ता आपके ऐप को सिस्टम- डिस्प्ले किए गए अलर्ट से खोलता है, तो सिस्टम इस पद्धति को फिर से कॉल कर सकता है जब आपका ऐप अग्रभूमि में प्रवेश करने वाला हो, ताकि आप अपने उपयोगकर्ता इंटरफ़ेस को अपडेट कर सकें और सूचना से संबंधित जानकारी प्रदर्शित कर सकें।

public func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) {
  if application.applicationState == .inactive {
    print("from push")
  }
}

आपके ऐप के आधार पर, यह आपको content-availableअंदर से साइलेंट पुश भी भेज apsसकता है, इसलिए इसके बारे में भी जागरूक रहें :) देखें https://stackoverflow.com/a/33778990/1418457


2
केवल एक उत्तर दें जो एक गंदे हैक की तरह महसूस नहीं करता है और सही है। यदि मैं गायब हूं, यदि ऐप पृष्ठभूमि में है और उपयोगकर्ता इसे मैन्युअल रूप से खोलता है, तो उसके लिए कैसे जांच करें? जबकि अभी भी पुश कोल्ड स्टार्ट और बैकग्राउंड से पुश करने की जांच कर रहा है।
जोहान

1
@ JochenÖsterreicher हाय, मैं इसे यहाँ सारांश, कृपया जांच करें medium.com/@onmyway133/...
onmyway133

19

स्विफ्ट 2.0 'रनिंग नहीं' राज्य के लिए (स्थानीय और दूरस्थ अधिसूचना)

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {


// Handle notification
if (launchOptions != nil) {

    // For local Notification
    if let localNotificationInfo = launchOptions?[UIApplicationLaunchOptionsLocalNotificationKey] as? UILocalNotification {

        if let something = localNotificationInfo.userInfo!["yourKey"] as? String {
            self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something))
        }


    } else

    // For remote Notification
    if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as! [NSObject : AnyObject]? {

        if let something = remoteNotification["yourKey"] as? String {
            self.window!.rootViewController = UINavigationController(rootViewController: YourController(yourMember: something))
        }
    }

}


return true
}

15

यह application:didReceiveRemoteNotification:जांचने के लिए कि आपके ऐप को अग्रभूमि या पृष्ठभूमि में होने पर आपको सूचना मिली है या नहीं।

यदि यह पृष्ठभूमि में प्राप्त हुआ था, तो अधिसूचना से एप्लिकेशन लॉन्च करें।

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo {
    if ([UIApplication sharedApplication].applicationState == UIApplicationStateActive) {
        NSLog(@"Notification received by running app");
    } else {
        NSLog(@"App opened from Notification");
    }
}

3
ध्यान दें कि "अधिसूचना से खोला गया एप्लिकेशन" एक गलत सकारात्मक होगा यदि अधिसूचना भेजी जाती है, जबकि उपयोगकर्ता एक अलग स्क्रीन पर होता है (उदाहरण के लिए, यदि वे स्टेटस बार को नीचे खींचते हैं और फिर आपके ऐप से एक अधिसूचना प्राप्त करते हैं)।
केविन कूपर

4
@ केविन बिल्कुल। यह आपको आश्चर्यचकित करता है कि ऐप्पल ने सूचनाओं को संभालने की प्रक्रिया को डिजाइन करने के लिए एक इंटर्न क्यों लगाया ...
एंड्रियास

यदि हम सक्रिय अवस्था में प्राप्त सूचना पर टैप करते हैं, तो हम कैसे पता लगा सकते हैं
मयंक जैन

13

तेजी के लिए:

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
    PFPush.handlePush(userInfo)

    if application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background {
        //opened from a push notification when the app was in the background

    }

}

4

हाँ, आप इस विधि द्वारा appDelegate में पता लगा सकते हैं :

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
      /* your Code*/
}

स्थानीय अधिसूचना के लिए:

- (void)application:(UIApplication *)application
didReceiveLocalNotification:(UILocalNotification *)notification
{
         /* your Code*/
}

1
यदि ऐप नहीं चल रहा है तो इस विधि को नहीं कहा जाता है। Thats यहाँ क्या पूछा
Pfitz

मेरी समस्या अधिसूचना को संभाल नहीं रही है, बल्कि यह जानने के लिए कि क्या यह बैनर क्लिक करने पर खोला गया था (जब ऐप पृष्ठभूमि पर है)।
जोओ

3

अगर कोई स्विफ्ट 3 में जवाब चाहता है

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable: Any]) {
    switch application.applicationState {
    case .active:
        //app is currently active, can update badges count here
        break
    case .inactive:
        //app is transitioning from background to foreground (user taps notification), do what you need when user taps here
        break
    case .background:
        //app is in background, if content-available key of your notification is set to 1, poll to your backend to retrieve data and update your interface here
        break
    default:
        break
    }
}

लेकिन अनुप्रयोग समाप्त होने पर पुश अधिसूचना टैप करके आवेदन खोला जाता है, तो कैसे पता करें
user3804063

1
जब कोई पुश पर टैप करता है, तो ऐप ओपन होगा, चाहे वह समाप्त हो या न हो। और। सक्रिय मामला कॉल कर रहा है
हामिद शाहसावरी

1
मुझे यह पता लगाने की ज़रूरत है कि क्या ऐप को टैप करके खोला गया है और मैं संबंधित सामग्री पर नेविगेट करना चाहता हूं जिसे मैंने इंस्टाग्राम पर देखा है
user3804063

स्थानीय सूचनाओं के बारे में कैसे?
अमीर शबानी

3

Xamarin उपयोगकर्ताओं के लिए यह पोस्ट करना।

यह पता लगाने की कुंजी कि क्या ऐप को एक पुश नोटिफिकेशन के माध्यम से लॉन्च किया गया था AppDelegate.FinishedLaunching(UIApplication app, NSDictionary options), वह विधि है, और विकल्प शब्दकोश जो इसमें पारित हो गया है।

यदि यह एक स्थानीय अधिसूचना है तो विकल्प शब्दकोश में यह कुंजी होगी UIApplication.LaunchOptionsLocalNotificationKey:।

यदि यह एक दूरस्थ सूचना है, तो यह होगा UIApplication.LaunchOptionsRemoteNotificationKey

जब कुंजी है LaunchOptionsLocalNotificationKey, वस्तु प्रकार की है UILocalNotification। फिर आप अधिसूचना को देख सकते हैं और निर्धारित कर सकते हैं कि यह कौन सी विशिष्ट अधिसूचना है।

प्रो-टिप: UILocalNotificationइसमें एक पहचानकर्ता नहीं है, उसी तरह से UNNotificationRequestकरता है। UserIfo में एक डिक्शनरी कुंजी रखें जिसमें एक requestId हो ताकि परीक्षण करते समय UILocalNotification, आपके पास एक विशिष्ट रिक्वेस्ट हो, जो आपके तर्क को आधार बनाने के लिए एक विशिष्ट अनुरोध उपलब्ध हो।

मैंने पाया कि iOS 10+ डिवाइसेस पर भी , जो UNUserNotificationCenter's AddNotificationRequest& ' का उपयोग करके लोकेशन नोटिफिकेशन बनाते हैं UNMutableNotificationContent, कि जब ऐप नहीं चल रहा है (मैंने इसे मार दिया है), और नोटिफिकेशन सेंटर में नोटिफिकेशन को टैप करके लॉन्च किया है, जिसमें डिक्शनरी अभी भी समाहित है UILocalNotificaitonवस्तु।

इसका मतलब यह है कि मेरा कोड जो अधिसूचना आधारित लॉन्च के लिए जांच करता है, वह iOS8 और iOS 10+ उपकरणों पर काम करेगा

public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
    _logger.InfoFormat("FinishedLaunching");

    if(options != null)
    {
        if (options.ContainsKey(UIApplication.LaunchOptionsLocalNotificationKey))
        {
            //was started by tapping a local notification when app wasn't previously running.
            //works if using UNUserNotificationCenter.Current.AddNotificationRequest OR UIApplication.SharedApplication.PresentLocalNotificationNow);

            var localNotification = options[UIApplication.LaunchOptionsLocalNotificationKey] as UILocalNotification;

            //I would recommended a key such as this :
            var requestId = localNotification.UserInfo["RequestId"].ToString();
        }               
    }
    return true;
}

2

के लिए प्रलेखन से सीधे

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo:nil

यदि ऐप चल रहा है और रिमोट नोटिफिकेशन प्राप्त करता है, तो ऐप नोटिफिकेशन को प्रोसेस करने के लिए यह तरीका कहता है।

इस पद्धति के आपके कार्यान्वयन को कार्रवाई का एक उपयुक्त पाठ्यक्रम लेने के लिए अधिसूचना का उपयोग करना चाहिए।

और थोड़ा बाद में

यदि पुश अधिसूचना आने पर ऐप नहीं चल रहा है, तो विधि ऐप लॉन्च करती है और लॉन्च विकल्पों के शब्दकोश में उपयुक्त जानकारी प्रदान करती है।

उस पुश सूचना को संभालने के लिए ऐप इस पद्धति को कॉल नहीं करता है।

इसके बजाय, आपका कार्यान्वयन

application:willFinishLaunchingWithOptions:

या

application:didFinishLaunchingWithOptions:

पद्धति को पुश नोटिफिकेशन पेलोड डेटा प्राप्त करने और उचित रूप से प्रतिक्रिया देने की आवश्यकता है।


2

: मैं एक राज्य चार्ट है कि मैं अपने स्वयं के उपयोग और अधिक सही यह कल्पना करने के लिए और अन्य सभी राज्यों पर विचार करने के लिए बनाया के साथ शुरू करेंगे https://docs.google.com/spreadsheets/d/e/2PACX-1vSdKOgo_F1TZwGJBAED4C_7cml0bEATqeL3P9UKpBwASlT6ZkU3iLdZnOZoevkMzOeng7gs31IFhD-L/pubhtml ? gid = 0 और एकल = true

इस चार्ट का उपयोग करते हुए, हम देख सकते हैं कि एक मजबूत अधिसूचना हैंडलिंग प्रणाली विकसित करने के लिए वास्तव में क्या आवश्यक है जो लगभग सभी संभव उपयोग मामलों में काम करता है।

पूर्ण समाधान ↓

  • नोटिफिकेशन RemoteNotification में स्टोर नोटिफिकेशन पेलोड
  • साफ़ में संग्रहीत अधिसूचना applicationWillEnterForeground और didFinishLaunchingWithOptions
  • ऐसे मामलों में जहां नियंत्रण सेंटर / अधिसूचना केंद्र खींच लिया निपटने के लिए, आप एक ध्वज का उपयोग कर सकते willResignActiveCalled और यह करने के लिए सेट झूठी शुरू में, करने के लिए सेट यह सच में applicationWillResignActive विधि,
  • में didReceiveRemoteNotification विधि, सूचनाएं (userInfo) केवल जब willResignActiveCalled गलत है बचाने।
  • रीसेट गलत पर willResignActiveCalled में applicationDidEnterBackground और applicationDidBecomeActive विधि।

नोट: एरिक के उत्तर पर टिप्पणियों में एक समान उत्तर सुझाया गया है, हालांकि, राज्य शीट सभी संभावित परिदृश्यों को खोजने में मदद करता है जैसा कि मैंने अपने ऐप में किया था।

कृपया नीचे पूरा कोड ढूंढें और नीचे टिप्पणी करें कि क्या कोई विशेष मामला संभाला नहीं गया है:

AppDelegate

class AppDelegate: UIResponder, UIApplicationDelegate {
  private var willResignActiveCalled = false

  func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
    NotificationUtils.shared.notification = nil
    return true
  }
  func applicationWillResignActive(_ application: UIApplication) {
    willResignActiveCalled = true
  }
  func applicationDidEnterBackground(_ application: UIApplication) {
    willResignActiveCalled = false
  }
  func applicationWillEnterForeground(_ application: UIApplication) {
    NotificationUtils.shared.notification = nil
  }
  func applicationDidBecomeActive(_ application: UIApplication) {
    willResignActiveCalled = false
    NotificationUtils.shared.performActionOnNotification()
  }
  func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    if !willResignActiveCalled { // Check if app is in inactive by app switcher, control center, or notification center
      NotificationUtils.shared.handleNotification(userInfo: userInfo)
    }
  }
}

NotificationUtils : यह वह जगह है जहां आप अपने सभी कोड को एप्लिकेशन के विभिन्न हिस्सों में नेविगेट करने के लिए लिख सकते हैं, डेटाबेस (CoreData / Realm) को हैंडल कर सकते हैं और अन्य सभी चीजें कर सकते हैं जो अधिसूचना प्राप्त होने पर करने की आवश्यकता होती है।

   class NotificationUtils {
  static let shared = NotificationUtils()
  private init() {}

  var notification : [AnyHashable: Any]?

  func handleNotification(userInfo : [AnyHashable: Any]){
    if UIApplication.shared.applicationState == UIApplicationState.active {
      self.notification = userInfo //Save Payload
      //Show inApp Alert/Banner/Action etc
      // perform immediate action on notification
    }
    else if UIApplication.shared.applicationState == UIApplicationState.inactive{
      self.notification = userInfo
    }
    else if UIApplication.shared.applicationState == UIApplicationState.background{
      //Process notification in background,
      // Update badges, save some data received from notification payload in Databases (CoreData/Realm)
    }
  }

  func performActionOnNotification(){
    // Do all the stuffs like navigating to ViewControllers, updating Badges etc
    defer {
      notification = nil
    }
  }
}

बेहतर यह एक टिप्पणी के रूप में डाल दिया क्योंकि यह जवाब नहीं है।
मैडी

@ मैडी सुझाव के लिए धन्यवाद, सभी विवरणों के साथ उत्तर अपडेट करें
चेतन आनंद

1
func application(_ application: UIApplication, didReceiveRemoteNotification data: [AnyHashable : Any]) {
    print("Push notification received: \(data)")

    if let info = data["aps"] as? Dictionary<String, AnyObject> {
        let alertMsg = info["alert"] as! String
        print(alertMsg)
        switch application.applicationState {
        case .active:
            print("do stuff in case App is active")
        case .background:
            print("do stuff in case App is in background")
           // navigateToChatDetailViewControler(pushdata: data)
        case .inactive:
            print("do stuff in case App is inactive")
            // navigateToChatDetailViewControler(pushdata: data)
        }
    }
}

1

केवल एक विश्वसनीय तरीका है, और यह केवल iOS 10+ के लिए काम करता है :

UNUserNotificationCenterकार्यान्वयन UNUserNotificationCenterDelegateविधि का उपयोग करना :

- (void) userNotificationCenter:(UNUserNotificationCenter *)center didReceiveNotificationResponse:(UNNotificationResponse *)response withCompletionHandler:(void (^)(void))completionHandler {

    //Here you can get your original push if you need to
    NSDictionary* pusDict = response.notification.request.content.userInfo;

    if ([response.actionIdentifier isEqualToString: UNNotificationDefaultActionIdentifier]) {
        //User tapped the notification
    } else if ([response.actionIdentifier isEqualToString: UNNotificationDismissActionIdentifier]) {
        //User dismissed the notification 
    } else if ([response.actionIdentifier isEqualToString: MYCustomActionId]) {
        //User chose my custom defined action
    }
    ...
}

0

आप उपयोग कर सकते हैं:

-(void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo

दूरस्थ पुश सूचनाओं को संभालने के लिए।

यहां दस्तावेज देखें



0
     // shanegao's code in Swift 2.0
     func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject])
    {
            if ( application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background ){
                    print("opened from a push notification when the app was on background")
            }else{
                    print("opened from a push notification when the app was on foreground")
            }
    }

लेकिन क्या हुआ अगर ऐप को बंद कर दिया गया (समाप्त कर दिया गया)। ट्विटर या इंस्टाग्राम की तरह यह किसी भी तरह से इसका पता लगाता है और यदि ऐप बंद हो जाता है तो यह आपको नई पोस्ट या चित्रों या आपकी प्रोफ़ाइल आदि पर रीडायरेक्ट करता है ..
Tarvo Mäesepp

0

इस प्रश्न के साथ समस्या यह है कि ऐप को "खोलना" अच्छी तरह से परिभाषित नहीं है। एक ऐप या तो एक न चलने वाले राज्य से कोल्ड-लॉन्च किया जाता है, या इसे एक निष्क्रिय स्थिति से पुन: सक्रिय किया जाता है (जैसे कि किसी ऐप से इसे वापस स्विच करना)। इन सभी संभावित अवस्थाओं को अलग करने का मेरा समाधान यहाँ है:

typedef NS_ENUM(NSInteger, MXAppState) {
    MXAppStateActive = 0,
    MXAppStateReactivated = 1,
    MXAppStateLaunched = 2
};

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // ... your custom launch stuff
    [[MXDefaults instance] setDateOfLastLaunch:[NSDate date]];
    // ... more custom launch stuff
}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler {
    // Through a lot of trial and error (by showing alerts), I can confirm that on iOS 10
    // this method is only called when the app has been launched from a push notification
    // or when the app is already in the Active state.  When you receive a push
    // and then launch the app from the icon or apps view, this method is _not_ called.
    // So with 99% confidence, it means this method is called in one of the 3 mutually exclusive cases
    //    1) we are active in the foreground, no action was taken by the user
    //    2) we were 'launched' from an inactive state (so we may already be in the main section) by a tap
    //       on a push notification
    //    3) we were truly launched from a not running state by a tap on a push notification
    // Beware that cases (2) and (3) may both show UIApplicationStateInactive and cant be easily distinguished.
    // We check the last launch date to distinguish (2) and (3).

    MXAppState appState = [self mxAppStateFromApplicationState:[application applicationState]];
    //... your app's logic
}

- (MXAppState)mxAppStateFromApplicationState:(UIApplicationState)state {
    if (state == UIApplicationStateActive) {
        return MXAppStateActive;
    } else {
        NSDate* lastLaunchDate = [[MXDefaults instance] dateOfLastLaunch];
        if (lastLaunchDate && [[NSDate date] timeIntervalSinceDate:lastLaunchDate] < 0.5f) {
            return MXAppStateLaunched;
        } else {
            return MXAppStateReactivated;
        }
    }
    return MXAppStateActive;
}

और MXDefaultsसिर्फ एक छोटा आवरण है NSUserDefaults


0

के लिये swift

 func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]){

    ++notificationNumber
    application.applicationIconBadgeNumber =  notificationNumber;

    if let aps = userInfo["aps"] as? NSDictionary {

        var message = aps["alert"]
        println("my messages : \(message)")

    }
}

0

Xcode 10 स्विफ्ट 4.2

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {

    let state : UIApplicationState = application.applicationState
    if (state == .Inactive || state == .Background) {
        // coming from background
    } else {
        // App is running in foreground
    }
}

0

IOS 10+ के लिए, आप इस पद्धति का उपयोग यह जानने के लिए कर सकते हैं कि आपका नोटिफिकेशन ऐप की स्थिति के बावजूद कैसे क्लिक किया गया।

func userNotificationCenter(_ center: UNUserNotificationCenter, didReceive response: UNNotificationResponse, withCompletionHandler completionHandler: @escaping () -> Void) {

    //Notification clicked
    completionHandler()
}

0

M.Othman के जवाब क्षुधा है कि शामिल नहीं है के लिए सही है दृश्य प्रतिनिधि के लिए दृश्य प्रतिनिधि ऐप्स इस पर मेरे लिए काम किया आईओएस 13

यहां इसके लिए कोड है जिसे दृश्य कनेक्ट में लिखा जाना चाहिए

if connectionOptions.notificationResponse == nil { 
//Not opened from push notification
} else {
  //Opened from push notification
}

पहले के संस्करणों का समर्थन करने के लिए एप्लिकेशन प्रतिनिधि के लिए कोड didFinishLaunchingWithOptions

let notification = launchOptions?[UIApplication.LaunchOptionsKey.remoteNotification]
        if (notification != nil) {

            //Launched from push notification
        } else {

            //Launch from other source
        }

-1

स्विफ्ट उपयोगकर्ताओं के लिए:

यदि आप पुश से खुलने पर या उस जैसे किसी अन्य पेज को लॉन्च करना चाहते हैं, तो आपको इसे इस didFinishLaunchingWithOptionsतरह से जांचना होगा :

let directVc: directVC! = directVC(nibName:"directVC", bundle: nil)
let pushVc: pushVC! = pushVC(nibName:"pushVC", bundle: nil)

if let remoteNotification = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? NSDictionary {
     self.navigationController = UINavigationController(rootViewController: pushVc!)
} else {
     self.navigationController = UINavigationController(rootViewController: directVc!)
}
self.window!.rootViewController = self.navigationController

डेलिगेट के पास कोई सदस्य नेविगेशनकंट्रोलर नहीं है
पाब्लो सेगर्रा

1
AppDelegate.h फ़ाइल में एक नेविगेशन नियंत्रक बनाएँ। यह प्रयोग कर रहा हूँ और यह काम करता है!
AAA

-1

स्विफ्ट में:

मैं पुश सूचनाएं (पृष्ठभूमि लाने के साथ) चला रहा हूं। जब मेरा ऐप बैकग्राउंड में होता है और मुझे एक पुश नोटिफिकेशन मिलता है, तो मैंने पाया कि appDelegate में didReceiveRemoteNotification दो बार कॉल किया जाएगा; एक बार जब सूचना प्राप्त होती है और दूसरा जब उपयोगकर्ता अधिसूचना चेतावनी पर क्लिक करता है।

यह पता लगाने के लिए कि क्या अधिसूचना चेतावनी पर क्लिक किया गया था, बस यह देखें कि क्या appState कच्चे मान == appDelegate में didReceiveRemoteNotification के अंदर है।

func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject: AnyObject]) {
    // If not from alert click applicationState(1)
    if (application.applicationState.rawValue != 1) {
        // Run your code here
    }
}

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


-1

जब एप्लिकेशन को आप उपयोग कर सकते हैं shanegao के रूप में पृष्ठभूमि में है

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo
{
    if ( application.applicationState == UIApplicationStateInactive || application.applicationState == UIApplicationStateBackground  )
    {
         //opened from a push notification when the app was on background
    }
}

लेकिन अगर आप एप्लिकेशन लॉन्च करना चाहते हैं और जब ऐप बंद हो जाता है और आप अपने एप्लिकेशन को डीबग करना चाहते हैं, तो आप एडिट स्कीम में जा सकते हैं और बाएं मेनू में रन का चयन करें और फिर लॉन्च में सेलेक्ट होने के लिए प्रतीक्षा करें लॉन्च होने का इंतजार करें और फिर जब आप एप्लिकेशन लॉन्च करें पुश नोटिफिकेशन पर क्लिक करें

योजना संपादित करें> चलाएँ> लॉन्च होने के लिए निष्पादन योग्य होने की प्रतीक्षा करें

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