In documentation for method
application:didReceiveRemoteNotification:fetchCompletionHandler:
said
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 push notification arrives.
I set 'background fetch' and 'Remote notifications' option in .plist and 'launch due to background fetch event' option in scheme settings.
If my app running foreground and received push, this method called and all seems ok.
But when i run my app from xCode and then move it to background mode (by pressing home button), it won't react on breakpoints or NSLogs in method above when push sent. System displays push notification, but i still can't do some actions when push arrives.
Is it possible to handle push notifications when app is running background?
Related
When i reboot my phone without opening my app, and send a remote notification with 'content-available' bit, my app is not launched or invoke the delegate. But I can get the notification alert. The app was even launched for scheduled background fetch! Once I started my app by tap icon, the delegate is invoked as expected even if my app is in background or killed(not force quit).
Am I misunderstanding Apple's doc of this method or I'm missing something in my implementation?
It's running on iOS 9.3.1.
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 push
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.
I'm implementing didReceiveRemoteNotification. I'm also saving these notifications locally. But I noticed if I'm at the home screen and don't open the notification, this function never gets called, and I can't save the notification. Any ideas?
You have to implement application:didReceiveRemoteNotification:fetchCompletionHandler: instead of application:didReceiveRemoteNotification:. See official documentation here:
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.
Also make sure to enable "remote notifications background mode", like stated in the documentation. Edit Info.plist and check the "Enable Background Modes" and "Remote notifications" check boxes:
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
Silent notifications work via Background modes and content available flag, but only if the app is in background.
Is it possible to know if/when the user received the notification, even when the app is suspended(not in background) ?
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.
Here is the relevant section from the documentation:
application:didReceiveRemoteNotification:fetchCompletionHandler:
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 push
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.
My app is receiving remote notifications (APNS) and is working for all the common scenarios:
App is not running (didFinishLaunchingWithOptions:)
App is running and active (didReceiveRemoteNotification:)
App is running, the phone is locked and I unlock the device as soon as I get the notification (didReceiveRemoteNotification:)
However, not if I in the last case choose not to unlock the device immediately (with the slider) and I wait until the screen goes black again. The message/notification is still shown in the lock screen, but the slider can now only unlock the device and when I do, didReceiveRemoteNotification: doesn't get called at all.
I’m afraid this is the intended behaviour. Quote the Local and Push Notification Programming Guide, part Scheduling, Registering, and Handling Notifications:
If the action button is tapped (…), the system launches the
application and the application calls its delegate’s
application:didFinishLaunchingWithOptions: method (…); it passes in
the notification payload (…). If the application icon is tapped (…),
the application calls the same method, but furnishes no information
about the notification.