Silent Push Notifications - Call CompletionHandler after timeout?

My iOS app uses silent push notifications via application:didReceiveRemoteNotification:fetchCompletionHandler to trigger background refreshes.

Occasionally a refresh will time out, and when the next silent notification comes in, the original process will complete.

Example:

  • SilentNotification SN1 with CompletionHandler CH1 is received

  • A background refresh process BR1 begins, but times out

  • SN2 later arrives, with CH2

  • BR1 continues now that iOS has awakened the app, and runs to completion (There's no BR2, since I'm able to detect that the BR1 is still able to be completed)


Which CompletionHandler do I call?


Should I hold onto CH1 and call it when the refresh completes, even though it's running in SN2's time allocation?

Do I call CH2 instead?

Both?

Replies

I’d like to clarify what you mean by “a refresh will time out”. Is this some internal operation that you’ve started in response the notification? If so, what API does that use?

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"
I was just referring to my background refresh code: getting JSON data from CloudKit, parsing, processing, etc. It's not a specific API that's timing out, it's that it appears that I'm timing out, since processing will just stop - and it's not while waiting on data, it's during processing of it. Surprisingly, the time elapsed is only a few seconds sometimes. I'm only able to tell from logging that the processing starts, stops for some reason (I've presumed this to be a timeout), and when the next silent push notification comes in, the processing picks back up right where it was suspended.

If it matters, I've tended to see this occur more - but not exclusively - on older devices (iPhone 6, 6s,...)

I was just referring to my background refresh code: getting JSON data
from CloudKit, parsing, processing, etc.

Ah. The basic idea here is to use a background task to keep your app from suspending while these operations are in progress. This will end in one of two ways:
  • The background task will expire, at which point you should prepare to suspend and then call the completion handler.

  • You’ll complete your work, in which case you should end the background task and then call the completion handler.

Both of these avoid you getting into the state described in your first post.

See my UIApplication Background Task Notes for more info about this sort of thing.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"