0

I've added push notifications to my app, and the notifications are sent with 'content-available'.

I'm seeing this wierd behviour that (usually) 2 of 5 notifications doesn't reach the app's application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) function BUT ONLY WHILE NOT DEBUGGING.

Yes, that right. There's a difference if I'm having the debugger attached or not.

In this scenario I always receive 5 out of 5 notifications in didReceiveRemoteNotification:

  1. Run app from Xcode
  2. Minimize it
  3. Send 5 notifications
  4. See 5 "system-notifications"
  5. didReceiveRemoteNotification is called 5 times.

In this scenario I usually receive 3 out of 5 notification in didReceiveRemoteNotification (sometimes 4).

  1. Run app from Xcode
  2. Unplug USB
  3. Minimize it
  4. Send 5 notifications
  5. See 5 "system-notifications"
  6. didReceiveRemoteNotification is called 3-4 times.

My didReceiveRemoteNotification is simple:

var received = 0

func application(_ application: UIApplication,
                 didReceiveRemoteNotification userInfo: [AnyHashable : Any],
                 fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    received += 1
    application.applicationIconBadgeNumber = received
    sleep(2) // do some "work", same behaviour with or without this line...
    completionHandler(.newData)
}

And then I just reset application.applicationIconBadgeNumber and received in applicationDidBecomeActive and didFinishLaunchingWithOptions.

  • Yes, I do send the notifications"fast". Basically I send them with a curl command, in a for-loop.
  • If I send with curl & (i.e start in parallel), I see the same behaviour.
  • If I send regularly (not parallel), I see the same behaviour.
  • If I send with curl ; sleep (i.e. wait 1 second between each curl cal) I get all of them.
  • The sleep that I added in didReceiveRemoteNotification for testing doesn't make any difference. My thought was that if notifications with 'content-availabe' was received while processing another in the background, it would drop any not send any 'content-availabe' to the app during this period.
netdigger
  • 3,659
  • 3
  • 26
  • 49
  • Push notifications are not guaranteed to be delivered; as you have found they can be rate limited. Apps often behave differently under the debugger, particularly with respect to background execution limitations that are removed while debugging. – Paulw11 Jul 13 '17 at 06:37
  • I do know that they are not guaranteed to be delivered, however I find it suspect that they'd "randomly" drop with the same behaviour. And, in this case, I always stay under 2~ish seconds, when 30 seconds is the limit, so that shouldn't be a problem. – netdigger Jul 13 '17 at 06:45
  • And actually, "There are no caps or batch size limits for using APNs" according to https://developer.apple.com/library/content/technotes/tn2265/_index.html#//apple_ref/doc/uid/DTS40010376-CH1-TNTAG23 https://developer.apple.com/library/content/technotes/tn2265/_index.html – netdigger Jul 13 '17 at 06:52
  • While there are no limits on the push notifications you can send, there are limits on the number that will be received when it comes to background execution; See https://stackoverflow.com/questions/21537929/are-there-rate-limits-on-silent-push-notifications-in-ios-7 and the article that that answer links to. You have pretty much shown this to be the case yourself; it works when you introduce a delay in the sending of the notifications. I suspect that if you observe the device log in the device window you may even find a message about the discarded pushes – Paulw11 Jul 13 '17 at 07:09
  • @Paulw11 From the PDF: **"Silent pushes are rate limited"**. It is NOT silent pushes that we send, we have an 'alert', a 'badge, and a 'sound'. – netdigger Jul 13 '17 at 08:21
  • `Content-available=1` == "silent push". The alert and sound are only shown if the app is terminated, otherwise the notification is delivered to your app delegate silently. I am not trying to be difficult here; you have proven the issue yourself; if you slow the rate of of delivery you get all messages. – Paulw11 Jul 13 '17 at 08:27
  • I'm not trying to be difficult either, but that's just not true. Got to https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CreatingtheNotificationPayload.html, read under "Configuring a Silent Notification", the requirements for a silent notification are: 1. The payload’s aps dictionary **must include the content-available key** with a value of 1, and 2. The payload’s **aps dictionary must not contain the alert, sound, or badge keys**. I.e a push that contains 'alert', etc. is **NOT** a Silent Notification. Can we agree on that? – netdigger Jul 13 '17 at 08:35
  • If you read the paragraph before that it explains that if those conditions aren't met then the alert may be displayed to the user instead of being delivered to your app; however it is the content-available=1 that prompts the delivery to your app delegate and this is the functionality that can be rate limited. You should not need to process content-available messages at a high rate – Paulw11 Jul 13 '17 at 08:44
  • I cannot exactly spot the paragraph you're referring to, but sure, it would make sense. But I still find it hard to grasp that it is in fact this limit that is the problem. I mean, they say "try not to send more than a few notifications per hour", but that doesn't play very well with *it's fine to send 5 notifications with payload in 5 seconds, but it's not ok to send 5 notifications in 1 second*. You see where I'm getting? These limits refer to some notifications in an hour, but my "testing" is the same, when I send 100 in 15 minutes. – netdigger Jul 13 '17 at 09:31
  • No intention to barge-in, but any notification which contains 'content-available' key (irrespective of alert, badge etc.) becomes low priority Push (Provided its not a Voip Push) & will get throttled. We have seen this throttling logic w.r.t. various parameters like charging, low battery, foreground, multiple notifications etc. By 'Few notifications per hour', I don't think Apple means that it won't throttle if app is receiving silent notification every second. – Ayush Jul 13 '17 at 11:17
  • @Ayush Feel free to join :) As much clarification as possible. – netdigger Jul 13 '17 at 12:48

0 Answers0