Advances in App Background Execution
Show Apple's description.
Background execution is a powerful tool your app can leverage to provide a great user experience. Learn about best practices to follow when running in the background, especially if you use VoIP or silent pushes, and an all-new scheduling API that enables long running processing and maintenance tasks.
Background Execution Best Practices
If we want something to happen now or almost now, even when the app goes to the background, we need to call:
- from main app:
- from extensions:
These objects give us more run time in the case our app is not in the foreground anymore. This api will ensure that our request goes through before the app gets suspended.
Discretionary Background URL Session
Defer the download to later, when is “later” is decided by the system (could be hours!). This is for downloading content that is not high priority (or batch analytics) and to do so when is more proper.
We can even set a the earliest time when to start a download and an estimate workload size so the system can make some assumption on when it is the right time to do so.
Note that, if we put it too far in the future, and the user never uses the app again, our task might never be executed.
- New in iOS 13
- Example of tasks that fit perfectly with this framework:
- Data Syncing
- Database Cleanup
- Backups Upload
Background Processing Tasks
- Several minutes of runtime at system-friendly times
- Option to turn off CPU Monitor for intensive work:
- at night when the device is charging we can do battery intensive work without worrying
Background App Refresh Task
- 30 seconds of runtime to update the app every time
- Called based on the user usage pattern: our app will get this refresh task before the user launches the app (again, based on the pattern) so that when the user launches the app all the new content has been downloaded already.
How to use
We will interact mainly via the
BGTaskScheduler, which is the interface to all of this intelligent scheduling.
To create a request, we will create an instance of either
BGAppRefreshTaskRequest, based on the task.
When the system is ready to give us time to do the task, the app will be launched (in the background) with a
Once we’re done, we will call
setTaskCompleted and let the app be suspended.
Based on the tasks we’ve given to the
BGTaskScheduler, our app will be given multiple tasks at the same time. However note that the time allotted for this is the same if it was one or multiple tasks.
All the tasks will be given to the main app, even when the background task was scheduled by an extension
- We need to have the background mode capability turned on with background fetch/processing ticked.
- Set the
info.plistkeys to tell iOS we support app background task/refresh. Add a key “Permitted background task scheduler identifiers” and use an array of strings as the value. This array contains unique strings that our apps must declare, each string declares a different task that the app wants to perform.
- Go in the app delegate and deal with the task:
- import BackgroundTasks
- Register a background task. Note how the last block of this function is what will be called when the system decides that it’s time to do the task. Remember to call
task.setTaskCompletedonce it is done.
- Lastly, schedule the task
Some cool properties of these requests:
earliestBeginDatetells the system to wait at least the time we pass to this method before calling the task
requiresNetworkActivity(for processing only) tells the system to wake up our app for the task only if we have connectivity (or if we don’t need connectivity to do our task)
requiresExternalPowertells the system we’re going to do intensive stuff and use lots of resources. Setting this to
truealso disables CPU Monitor, allowing the app to do intensive work with no throttling.
After scheduling the task, we can mock/force a system call to activate our scheduled task via the debugger with:
e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"TASK_IDENTIFIER"]
TASK_IDENTIFIER with the task name.