Push notifications not working properly when the a

2019-05-24 23:22发布

问题:

I'm facing a problem with push notifications, I'm using Google Cloud Messaging,

My problem is that my app works with some cached data, and I refresh that cache with the data coming from push notificacions, so when the app is killed by the user (home button + swipe-up) and the app receive a push notification it doesn't call the method didReceiveRemoteNotification, so the app can't access to the payload of that notification and update the cached data.

So, is there a way to achieve this?

Only when the user taps the notifications and the app gets it through the application:didFinishLaunchingWithOptions method?

If the user opens the app by clicking the application icon I can't get the notificaton's payload?

PD: If the app is in foreground or background (not killed) it works perfectly

回答1:

If you wish your app to receive the push notification even when it is killed, add the key "content-available":"1" to the push payload.

Look here

EDIT: After digging some more, I found out that silent push (e.g content-available:1), does not wake the app if it was killed by the user:

However, the system does not automatically launch your app if the user has force-quit it

I must say, I can't really understand why the OS does not let my app wake up when silent push arrives when it's dead. What's the point then???



回答2:

This is the expected behavior. didReceiveRemoteNotification will not be called if the user killed the app, unless your app has VoIP permissions.



回答3:

In case of killed application. both application:didFinishLaunchingWithOptionsandapplication:didReceiveRemoteNotification:fetchCompletionHandler:are called. In the prior one. The key of notification either remote or local is passed in options parameter. And the later one is called in only case when remote notification. The process is explained in detail in Apple Docs Here. The snapshot is pasted here as well.

Handling an Actionable Notification

If your app is not running in the foreground, to handle the default action when a user just swipes or taps on a notification, iOS launches your app in the foreground and calls the UIApplicationDelegate method application:didFinishLaunchingWithOptions: passing in the local notification or the remote notification in the options dictionary. In the remote notification case, the system also calls application:didReceiveRemoteNotification:fetchCompletionHandler:.

If your app is already in the foreground, iOS does not show the notification. Instead, to handle the default action, it calls one of the UIApplicationDelegate methods application:didReceiveLocalNotification: or application:didReceiveRemoteNotification:fetchCompletionHandler:. (If you don’t implement application:didReceiveRemoteNotification:fetchCompletionHandler:, iOS calls application:didReceiveRemoteNotification:.)

Finally, to handle the custom actions available in iOS 8 or newer , you need to implement at least one of two new methods on your app delegate, application:handleActionWithIdentifier:forRemoteNotification:completionHandler: or application:handleActionWithIdentifier:forLocalNotification:completionHandler:. In either case, you receive the action identifier, which you can use to determine what action was tapped. You also receive the notification, remote or local, which you can use to retrieve any information you need to handle that action. Finally, the system passes you the completion handler, which you must call when you finish handling the action. Listing 2-8 shows an example implementation that calls a self-defined action handler method. Reference Apple Docs

Edit:

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. Reference: Apple Docs



回答4:

When the app is killed and the push notification triggered contains some actionable button. When we click on a Action Button of Push Notification then:

The first delegate that is executed is:

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

But in here the launchOptions are nil.

The second delegate that is executed is:

-(void)application:(UIApplication *)application handleActionWithIdentifier:(nullable NSString *)identifier forRemoteNotification:(nonnull NSDictionary *)userInfo completionHandler:(nonnull void (^)())completionHandler

In this the variable userInfo contains all the payload of the Push Notification. With the help of identifier we can identify which action was invoked and then perform our respective operations.



回答5:

add target of notification service extension in your project it contains two methods upper one method call in killed time and add a key "mutable_content" : true in server side of your notification payload