iOS 10 silent push notification not triggering backgrounded app
Asked Answered
B

4

15

I have an app in which I'm trying to receive and handle SILENT push notifications.

I'm registering for APNs as follows:

UNUserNotificationCenter.currentNotificationCenter().delegate = self
UNUserNotificationCenter.currentNotificationCenter().requestAuthorizationWithOptions([.Badge, .Sound, .Alert]) {(granted, error) in
    if granted {
        application.registerForRemoteNotifications()
    }
}

Implemented:

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
    // Handle notification
}

func userNotificationCenter(center: UNUserNotificationCenter, willPresentNotification notification: UNNotification, withCompletionHandler completionHandler: (UNNotificationPresentationOptions) -> Void) {
    // Handle notification
}

The app has UIBackgroundModes fetch and remote-notification

The APN content looks like:

{
    "aps":{
        "content-available":1,
        "badge":0
    },
    "action":"shareDelete",
    "shareId":633
}

When the app is in the foreground, userNotificationCenter(centre:withCompletionHandler:willPresentNotification) is fired when the notification is received, but when the app is backgrounded, nothing happens.

I can see the APN is received by changing the badge number, but nothing is triggered in app.

What am I missing?

(Also asked on Apple dev forums)

Bertha answered 3/11, 2016 at 16:9 Comment(11)
I am unaware of the reason for issue above, But if you are trying to handle SILENT notification you could have used "didReceiveRemoteNotification" delegate method & use "[[UIApplication sharedApplication] applicationState] == UIApplicationStateBackground" to handle it.Improvvisatore
This is for iOS 10 - has new delegate methods (right?)Bertha
No, I meant that since you want to handle silent notification you can make use of the existing "didReceiveRemoteNotification" and handle it, instead of looking for "willPresentNotification" to handle it in there.Improvvisatore
Thanks, but I tried all delegate methods… and none get fired with a silent notificationBertha
One last time please try this delegate method "didReceiveRemoteNotification:fetchCompletionHandler:" 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.Improvvisatore
@AshleyMills did you find the problem? I have the same one. I receive normal pushes, but userNotificationCenter:didReceiveNotificationResponse isn't calledLookout
@AshleyMills any luck with this?Scurrile
I'm afraid not.Bertha
@AshleyMills This might be late... For an iOS device to receive a silent notification the APN content should not include the 'badge' key?Zwieback
Is the app still running or is it killed? If it's killed it might be delivering the payload in the launchOptions dictionaryRudderhead
@AhmedAbdelHadyKhedr is right, for the APNs to be Silent, it can't contain (badge, sound, alert) on payload.Khartoum
L
5

Method

func userNotificationCenter(center: UNUserNotificationCenter, didReceiveNotificationResponse response: UNNotificationResponse, withCompletionHandler completionHandler: () -> Void) {
    // Handle notification
}

called when user taps on notification or check it on Apple Watch:

Called to let your app know which action was selected by the user for a given notification.

You need to implement the old method

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {

}
Lookout answered 17/11, 2016 at 20:28 Comment(1)
This is confusing from Apple. They replaced most of the previous framework but still decided to keep this one last old delegate method. I guess there focus was for when there's a user interaction...Jellify
V
0
UNUserNotificationCenter *center = [UNUserNotificationCenter currentNotificationCenter];
center.delegate = self;
NSLog(@"%@",center.delegate);

Checkout if the center.detegate is still AppDelegate, in my case, it was changed to something like X****Delegate, so, willPresentNotification and didReceiveNotificationResponse were never called.

Varlet answered 28/12, 2020 at 10:11 Comment(0)
P
-1

Are you setting minimumBackgroundFetchInterval? As mentioned in the docs:

The minimum number of seconds that must elapse before another background fetch can be initiated. This value is advisory only and does not indicate the exact amount of time expected between fetch operations.

The default fetch interval for apps is UIApplicationBackgroundFetchIntervalNever. Therefore, you must call this method and set a fetch interval before your app is given background execution time.

So if you're not setting this it's quite possible your fetch handler will never be called in the background.

Promisee answered 3/11, 2016 at 16:31 Comment(0)
B
-3

When your application is in the background or not running the only way for your app to be notified is if the user select an action linked to to your notification.

See Local and remote notifications guide.

When your app is not running or is in the background, the system automatically delivers local and remote notifications using the interactions you specified. If the user selects an action, or chooses one of the standard interactions, the system notifies your app of the user’s selection. Your code can then use that selection to perform additional tasks. If your app is running in the foreground, notifications are delivered directly to your app. You can then decide whether to handle the notification quietly or alert the user.

To respond to the delivery of notifications, you must implement a delegate for the shared UNUserNotificationCenter object. Your delegate object must conform to the UNUserNotificationCenterDelegate protocol, which the notification center uses to deliver notification information to your app. A delegate is required if your notifications contain custom actions.

here is the source: https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/SchedulingandHandlingLocalNotifications.html#//apple_ref/doc/uid/TP40008194-CH5-SW14

Balanchine answered 5/4, 2017 at 14:18 Comment(6)
This is incorrect. "Silent" push notifications can be delivered that require no user interaction… developer.apple.com/library/content/documentation/…Bertha
Yes it is delivered but handle by the system. your app is not notify until the user select an actionBalanchine
Again, this is incorrect. "silent" notifications should be delivered to the app without user interaction (that's why they are silent) Please follow the link in my previous comment.Bertha
Sorry that but this is not my invention. don't be so stubborn and read the doc for a secondBalanchine
see the related issue #14616761Balanchine
Can confirm: Fitzgerald, despite his accusations that the other here is stubborn, is wrong. Totally wrong. Nice one dude.Latoria

© 2022 - 2024 — McMap. All rights reserved.