How to catch all iOS Push Notifications with different user actions including tap on app icon

21,383

Solution 1

You can't, you will only receive information about the notification that was used to open your app.

So if a user opens your app, and your app has notifications, you will not be able to retrieve them from with in your app.

A work around could be to also keep track of notification on a server and handle this with in the app. Thus the server keeps track on which notification has been read. This is how Facebook does it.

Solution 2

To do it in a right way, some conditions must be met:

Your server knows about what your app currently have seen and what notifications it could send once again.

Let's consider only remote notifications. There are three states of app:

  • FOREGROUND:

    • notification appears without user's action:

      func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
          //handle your notification
      }
      

    You can display banner using third party library: BSForegroundNotification

  • BACKGROUND

    • notification appears on the screen. (Note that setting content-available=1 in a push notification can lead to the latest push message being visible once the app icon is pressed, as didReceive... is called).

      //nothing is called in the app, but app icon badge changes
      // OR - if the notification contains the field content-available set to 1 - 
      func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
          //handle your notification
      } 
      
    • user tap on notification

      func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
          //handle your notification
      }           
      
    • user take notification action

      func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
           //handle your notification's action
      }
      

      or

      func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
           //handle your notification's action response info
      }
      
    • user tap app icon

      func applicationDidBecomeActive(application: UIApplication) {
          //fetch pending notifications from server
      }
      
  • NOT RUNNING AT ALL

    • notification appears on the screen.

      //nothing is called in the app, but app icon badge changes
      
    • user tap on notification

      func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
          if let userInfo = launchOptions?[UIApplicationLaunchOptionsRemoteNotificationKey] as? [NSObject: AnyObject] {
              //handle your notification
          }
      }
      
    • user take notification action

      func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
           //handle your notification's action
      }
      

      or

      func application(application: UIApplication, handleActionWithIdentifier identifier: String?, forRemoteNotification userInfo: [NSObject : AnyObject], withResponseInfo responseInfo: [NSObject : AnyObject], completionHandler: () -> Void) {
           //handle your notification's action response info
      }
      
    • user tap app icon

      func applicationDidBecomeActive(application: UIApplication) {
          //fetch pending notifications from server
      }
      

How to handle notification?

  1. let notification = WLNotification(userInfo: userInfo)

    Within WLNotification remember to keep current application state when you receive notification. In future you may need it to know where that notification come from.

  2. WLNetworkClient.sharedClient().notificationForIdentifier(notification.identifier)

    Fetch from server details about that notification, and in the same time let it know that you REALLY get that notification, and effected on user's data.

How to fetch all pending notifications?

WLNetworkClient.sharedClient().pendingNotificationsWithCompletionBlock(nil)

Fetch all notifications you missed. in other words, fetch those ones, which were not marked in server as received by you.

Read Limitations of Apple Push Notifications.

See the related questions:

Solution 3

I had the same problem: if user clicks on push banner he gets info of push in app, if he clicks on app icon he doesn't get it. You can handle derivative one from it, but with some limits only. Example, if you want to have a badge number from push, you can do it: (Push -> App icon -> App icon badge -> your var)

in AppDelegate

- (void)applicationWillEnterForeground:(UIApplication *)application
{ 
    newMessages = application.applicationIconBadgeNumber;
}

Solution 4

Conceptually when application is loaded with clicking alert view presented for Push notification, than application is launched with didReceiveLocalNotification delegate method if your application is in background. At this point applicationDidFinishLaunching delegate method is not called.

When your application is not in background, clicking alert view presented for Push notification will call applicationDidFinishLaunching method.

Hope this clears your understanding between these 2 delegate methods.

Share:
21,383

Related videos on Youtube

Kirity
Author by

Kirity

Updated on July 09, 2022

Comments

  • Kirity
    Kirity almost 2 years

    As per the Apple guide:

    "As a result of the presented notification, the user taps the action button of the alert or taps (or clicks) the application icon. If the action button is tapped (on a device running iOS), the system launches the application and the application calls its delegate’s application:didFinishLaunchingWithOptions: method (if implemented); it passes in the notification payload (for remote notifications) or the local-notification object (for local notifications).

    If the application icon is tapped on a device running iOS, the application calls the same method, but furnishes no information about the notification . If the application icon is clicked on a computer running Mac OS X, the application calls the delegate’s applicationDidFinishLaunching: method in which the delegate can obtain the remote-notification payload."

    My question is Suppose user got 3-4 Push notifications from provider and all are stored in apple's notification center. If user tapped on notification alert, he/she can easily get the notification data in the app. But if user tapped app icon on iPhone, how to get all the data related of all previous notifications.

    Thanks in advance!

  • Kirity
    Kirity almost 12 years
    Thanks man! Actually I also had the same thoughts. But I was not sure. So that means to read the notification, user has to click on the notification bar. Right?
  • rckoenes
    rckoenes almost 12 years
    Yes, and you will only receive the notification that the user clicked on.
  • mskw
    mskw almost 11 years
    Come again, after keeping track of which one is read, do you mean that the server will resend the ones in proprietary fashion when the App connects to the facebook server?
  • Awais Tariq
    Awais Tariq almost 11 years
    I wonder why apple don't care about these basic issues.. Android is way good in handling push notifications..
  • Andrew
    Andrew over 9 years
    That's for local notifications, not push notifications.
  • DenVog
    DenVog about 9 years
    I wonder if applicationDidBecomeActive might be a better place to test? In my case, I was wanting to display an alert.
  • gerram
    gerram about 9 years
    Sure, you can use applicationDidBecomeActive. It depends on your logics order for waking up of app. Method applicationWillEnterForeground launch before applicationDidBecomeActive.
  • lagouyn
    lagouyn about 8 years
    ...and doesn't scheduledLocalNotifications only keep track of local notifications that have been scheduled, but not yet received? I think the original poster was asking about notifications that were received on the device, but that were not tapped. I, too, am interested to find out if this is possible with local notifications.
  • Arpit Kulsreshtha
    Arpit Kulsreshtha almost 6 years
    Excellent @Bartłomiej Semańczyk