I previously posted a topic about receiving application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
callback when my app is not running, and the system starts the app in the background to respond to a notification.
While I receive the callback reliably, the work performed by the callback seems to have different restrictions whether the app is in the background or not running.
When the app is running in the background, the work started in this callback completes reliably (in my case it takes no more than a few seconds), and I can post the result back to the system via the completion handler.
When the app is not running and the system starts it in the background, the app starts the same work, but this work seems to be terminated quickly without being able to complete, and without me being able to call the completion handler passed to the callback. I’m not talking about 30 seconds - the termination seems to happen after less than a second, which is not enough for my app.
The nature of the work shouldn’t matter, but just in case: I start a Task
in the callback for some asynchronous work, which stores the completion handler, and calls back to it when the work is finished. This happens completely reliably when the app is running in the background, and not at all reliably when the app is not running and is started by the system.
Why would application(_:didReceiveRemoteNotification:fetchCompletionHandler:)
behave differently based on if it is ran when the app is already running, vs not running and started by the system?
Is there anything I can do on my side to make it more reliable?
When an app is given background execution time for remote notifications (and most any background execution), there is a time limit of about 10 seconds, after which the app will be suspended.
This 10 seconds start the moment the app is launched or woken up (if not terminated). The difference with a terminated app is it goes through the usual app lifecycle and the various application delegate functions are called; for example didFinishLaunchingWithOptions()
. If this or other functions that are called when the app initializes are taking a lot of time (for example, if you are initializing a database, or some other synchronous work), that will be deducted from the ~10 seconds and you may not have much time left to handle the remote notification.
What I would suggest is to start by profiling the time spent when the app is launched in the background before didReceiveRemoteNotification()
is called.
Also, if you are suspecting that the app is being terminated within seconds after being launched, then it is very likely crashing, and you would want to look at some crash logs, or use common debugging techniques to find out why the app might be crashing when launched in the background.
Argun Tekant / DTS Engineer / Core Technologies