iOS 10 Remote Notifications When App Not Running - ios

When I receive a remote notification I updated a counter that I save to UserDefaults and I also show a local notification. Everything works as expected when the app is in the foreground, background, and suspended states Ref. When the app is in the Not Running state my counter is not updated nor is my local notification shown.
It is my understanding that I should be able to receive and process Remote Notifications while the app is completely off. A few articles online claim that when a Remote Notification arrives while in the Not Running state that the application:didFinishLaunchingWithOptions: should be called followed by application: didReceiveRemoteNotification:fetchCompletionHandler: but in my case it is not.
Is it possible to receive remote notifications while in Not Running state?

If your app is a VoIP app and you are using VoIP pushes through PushKit then a push notification will launch your app from the terminated state in order to deliver the notification. If you are using standard push notifications then your app will not receive the notification if it is terminated. You can include an alert text with a 'silent' notification that will be displayed to the user in the event that your app is terminated in order to prompt them to launch your app.

First of all, it sounds like you have a silent notification set up. Once you add alert data to your push notification (information like the title, body etc.. you can find more on that here), it'll start to display on the lock screen.
Second, it's not possible for your application to launch from a push notification, silent or otherwise, if it's in the Not Running state. The documentation on this is actually incorrect, as it states that the application will only not be launched if the user has quit the app. However, this actually also applies for any circumstance under the not-running state, for example if your app has never been launched since installation/rebooting, or if it was quit due to memory (a fairly common occurrence - iOS purges apps which haven't been run recently as required).

did you check this mark when app is background?

Related

How to wake up a not running app when receiving remote notifications

Right now I have a framework that receives a silent notification, get the data from it (custom data) and translate it into a local notification to show the alert to the user (this is donde in didReceiveRemoteNotification:fetchCompletionHandler method). I have implemented this framework on an app and everything seems to be working correctly, silent notifications are being process when the app is in background and foreground. However, when the app is killed by the user or it is not running, I cannot receive notifications because of this:
Use this method to process incoming remote notifications for your app.
Unlike the application:didReceiveRemoteNotification: method, which is
called only when your app is running in the foreground, the system
calls this method when your app is running in the foreground or
background. In addition, if you enabled the remote notifications
background mode, the system launches your app (or wakes it from the
suspended state) and puts it in the background state when a remote
notification arrives. However, the system does not automatically
launch your app if the user has force-quit it. In that situation, the
user must relaunch your app or restart the device before the system
attempts to launch your app automatically again.
The reason I use this method for showing notifications is because the payload I sent to APNS has custom data with key-values that indicate how the notification must behave.
I've been doing some research and I found that Pushkit for VoIP can do the job. However, many post suggest that this can cause app rejection.
So my question is, how can I achieve receiving remote notifications even if my app was killed and considering that data in the payload has custom information to build the notification?
Silent push notifications are unreliable: they might get delayed, delivered in groups or even not delivered at all.
If you need to modify the content of the notification before presenting a banner for the user, you should use a Notification Service App Extension. You can also share some information between your app and this extension - using app groups or the keychain - if it needs something from your app to process the notification data.

Notify the app about remote push notification when the app is not running (terminated)

When app is not running (terminated NOT in background) and a remote push notifications is received, is there any way to inform the app about it so that the app can update something locally such as simple int counter?
I want to store something so that when the app is launched the next time, app knows that notification was received when app wasn't running and something needs to be done.
If user launches an app by tapping on a notification, obviously the app is notified about it through AppDelegate methods but these methods are never called if user launches an app by tapping on the app's icon.
To be aware of notification when user launches app by tapping on icon, i need some way to let app know that notification was received when app was in background.
There is no way you can achieve this with simple push notifications.
According to apple docs if the user has manually killed your application by swiping it out of memory, your app will never be started in the background to process data until after the user chooses to launch it again.
One solution to this problem is using VOIP push.
According to apple docs -
Your app is automatically relaunched if it’s not running when a VoIP
push is received.
But you need a strong reason for using it and apple may ask that before approving your app on the app store.
To read more about VOIP push please go through this doc - https://developer.apple.com/library/content/documentation/Performance/Conceptual/EnergyGuide-iOS/OptimizeVoIP.html
You can also be used the "Silent Push Notifications".Which are confirming that their is something available on the server, which you need to download to your app,The payload format of the Silent push notification is like
{ content-available:1 }
The Best part of the silent notification is that they do not notify the iPhone user
Here 1 is for their is something available to download from the server.
here below i have attached the apple's silent notification slide.
Your App is getting Refresh in the Background.

Handle remote notifications when phone is locked/app not running

I'm using a combination of Firebase and Batch for a chat like application.
When a push notification is received the app should be able to perform some tasks based on the data received in the notification.
From my understanding this can only be done in app states suspended -> active and not terminated.
I have it working when the app is in the foreground and also when closing the app via home button.
Should the device be locked however, didReceiveRemoteNotification:fetchCompletionHandler: is never called. At least not until the user interacts with the notification from notification center.
Is this correct? Can no work be done on a remote notification if the device is locked?
I have all the appropriate entitlements and "content-available":1 set correctly.
Is there another way that I can wake the app up from a notification and do a few background tasks? I also tried using Notification Service Extension but had the same issue with nothing happening while the device was locked.

Remote notification is not delivered to my app after phone reboot

According to Apple's documentation on remote notifications:
Discussion
Use this method to process incoming remote notifications for your app.
Unlike the application:didReceiveRemoteNotification: method, which
is called only when your app is running in the foreground, the system
calls this method when your app is running in the foreground or
background. In addition, if you enabled the remote notifications
background mode, the system launches your app (or wakes it from the
suspended state) and puts it in the background state when a remote
notification arrives. However, the system does not automatically
launch your app if the user has force-quit it. In that situation, the
user must relaunch your app or restart the device before the system
attempts to launch your app automatically again.
In my case (iOS 7.1.1) remote notification is not delivered to the app after the app was killed (swipe up from Recent Apps List) and the phone was restarted. If I open the app, notifications get delivered as expected. What am I missing?
Edit: To avoid any misunderstanding. What I expect is the following flow:
User kills the app;
User restarts the phone;
App server sends a new message;
OS attempts to launch the app and deliver the notification.
The problem is that you are a developer, and your usage is not typical. What you do: Launch the app, swipe it out, turn off the phone (not standby, but turned off), reboot, enter your passcode, make your server send a notification. That doesn't work.
For some reason, notifications sent within 90 seconds or so after rebooting the phone are not received. Wait 90 seconds, then you send the notification, and it should be received. Since there is no relation between the time the phone of the user is rebooted and the time you send the notification, this is only a problem for developers and testers, not for real users.
From the article you linked, for the method you're referencing (application:didReceiveRemoteNotification:)
If the app is not running when a remote notification arrives, the
method launches the app and provides the appropriate information in
the launch options dictionary. The app does not call this method to
handle that remote notification. Instead, your implementation of the
application:willFinishLaunchingWithOptions: or
application:didFinishLaunchingWithOptions: method needs to get the
remote notification payload data and respond appropriately.
Are you checking for your remote notification payload in the options dictionary for the will/didFinishLaunchingWithOptions:?

iOS background fetch clears previous notifications

It looks like no matter I return UIBackgroundFetchResultNewData or UIBackgroundFetchResultNoData from performFetchWithCompletionHandler, it clears all previous notifications (local or push) for my app. This is not acceptable for me.
Anyone knows how do I do fetch and not make previous notifications cleared (disappear)?
My guess here is that you had a background fetch that was setting your badge number to 0, if that ever happens all your notifications are cleared.
Source: Apple's AppDelegate API Reference
application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
Tells the app that a remote notification arrived that indicates there is data to be fetched. Use this method to process incoming remote notifications for your app. Unlike the
application(_:didReceiveRemoteNotification:)
method, which is called only when your app is running in the foreground, the system calls this method when your app is running in the foreground or background. In addition, if you enabled the remote notifications background mode, the system launches your app (or wakes it from the suspended state) and puts it in the background state when a remote notification arrives. However, the system does not automatically launch your app if the user has force-quit it. In that situation, the user must relaunch your app or restart the device before the system attempts to launch your app automatically again.
If the user opens your app from the system-displayed alert, the system may call this method again when your app is about to enter the foreground so that you can update your user interface and display information pertaining to the notification.
Note: You need to make sure that the app is checking for the state before settings the application's badge number to 0. Test the below cases:
Application running, receives a notification
Application terminated, receives a notification
Launch app directly from app icon
Launch app from notification received
Knowing the difference between the 3 approached below is essential in your use case.
Checking the notification object received in application(_:didReceiveRemoteNotification:)
Checking the notification object received in application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
Checking the didFinishLaunchingWithOptions for UIApplicationLaunchOptionsRemoteNotificationKey

Resources