Nitish Nitish - 4 months ago 25
Objective-C Question

Delegate called when push notification arrives (not received) on a device

I am aware that when a push notification arrives on the device (and app does not opens it), there isn't a way to check that (I might be wrong). But there is one such case in my app, where it is imperative to know that the notification has arrived the device.

I have multiple tabs in the app out of which 2 have badge implementation depending on push notification. So basically there are two different types of push notifications.

Suppose if one type of notification arrives the device and user chooses not to see the notification. That way, the badge count of the tab is to be incremented by 1. But the issue is, which one. Because at the time, I open the app, I don't have the information, which notification type has arrived. Or to be precise, which tab badge count is to be incremented.
So in a nutshell, how do I know, notification has arrived the device (not received)?

Answer

There is no way to get this information using public API's.

From Local and Remote Notifications Programming Guide:

Let’s review the possible scenarios that can arise when the system delivers a local notification or a remote notification for an app.

The notification is delivered when the app isn’t running in the foreground. In this case, the system presents the notification, displaying an alert, badging an icon, perhaps playing a sound, and perhaps displaying one or more action buttons for the user to tap.

The user taps a custom action button in an iOS 8 notification. In this case, iOS calls either application:handleActionWithIdentifier:forRemoteNotification:completionHandler: or application:handleActionWithIdentifier:forLocalNotification:completionHandler:. In both methods, you get the identifier of the action so that you can determine which button the user tapped. You also get either the remote or local notification object, so that you can retrieve any information you need to handle the action.

The user taps the default button in the alert or taps (or clicks) the app icon. If the default action button is tapped (on a device running iOS), the system launches the app and the app calls its delegate’s application:didFinishLaunchingWithOptions: method, passing in the notification payload (for remote notifications) or the local-notification object (for local notifications). Although application:didFinishLaunchingWithOptions: isn’t the best place to handle the notification, getting the payload at this point gives you the opportunity to start the update process before your handler method is called.

For remote notifications, the system also calls the application:didReceiveRemoteNotification:fetchCompletionHandler: method of the app delegate.

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

As you can see, only tapped notification is to be examined when app is starting from killed state or undocked.

Another important point is:

Quality of Service

Apple Push Notification service includes a default Quality of Service (QoS) component that performs a store-and-forward function. If APNs attempts to deliver a notification but the device is offline, the notification is stored for a limited period of time, and delivered to the device when it becomes available. Only one recent notification for a particular app is stored. If multiple notifications are sent while the device is offline, the new notification causes the prior notification to be discarded. This behavior of keeping only the newest notification is referred to as coalescing notifications.

If the device remains offline for a long time, any notifications that were being stored for it are discarded.

So, long story short, delivery & presence of push-notifications are highly expectable, but not guaranteed. Also, path of push notification on device is not to be controlled programmatically - as an app, you subscribe to APNS daemon on device and you're dependent on it in terms of push notifications.

That is why, if your app has some business logic (in you case, counters update), you shouldn't rely on push notifications. You should use more reliable / controllable mechanism of syncing data between your app and backend. I've achieved this goal few times by using REST and dedicating Notification entity in my app's problem domain - user can GET notifications, mark them as read/unread, delete them etc via REST API.

Comments