N/A

In this article, we will explore the BackgroundTasks framework unveiled at this year's WWDC by Apple. This new framework offers a range of features to schedule and manage background tasks, allowing us to customize their execution conditions based on factors such as battery charging and network connectivity. With different types of tasks available, let's dive into each and see how they can be utilized.

Implementing a background app refresh

BGAppRefreshTask is a special type of Background Task which we can use for app data updates. One thing that makes this task type very special is user behaviour. iOS learns how often and at what time the user is running your app and tries to run BGAppRefreshTask at a time when the user is not likely to be using the app.

Let's implement a background app refresh for the sample app. First, we have to add background modes' capability in the project settings. Next, we need to enable "Background fetch" checkbox, which is required for background app refresh. Lastly, we need to add "Permitted background task scheduler identifiers" key to Info.plist. This key will store the array of unique identifiers for every background task in the app. Finally, we can start working on the background refresh logic.

  

We start by registering the task identifier and associated closure. This closure will run on every job execution. In handleAppRefresh function, we run the background operation.

There are 2 key points here:

  1. Make sure you call the setTaskCompleted method as soon as your job is finished.
  2. Set expiration handler on task object because the system gives you a limited time to complete your job, and if you exceed it, you have to clean up resources.

Remember that you can only schedule a job once, you have to schedule it every time if you want to run it periodically.

  

Background Processing task

Another type of background tasks is a Processing task. You can use it to train a ML model on-device or make a clean up in the database. Before you start, enable "Background processing" checkbox in Background Modes capability. Let's add another identifier for a new job type to Info.plist.

  

Scheduling a processing task is very similar to the app refresh task. Please take a look at scheduleMLTrain function. We set requiresExternalPower and requiresNetworkConnectivity properties to true. By doing this, we indicate that our job needs a network connection and battery charging. I highly encourage you to do your heavy calculations while the device is charging to prevent battery drain and a bad user experience.

How to debug it?

The only way of debugging background tasks is to keep your phone connected to Xcode debugger, but we don't know when iOS will decide to run our jobs because it uses some hidden logic for that. Luckily, Apple provides two private functions, which we can use in the debugger to start and expire background tasks. Please remember that you can use it only during development, don't include them in release.

For starting background tasks, pause your app and run in the debugger this code:

  

To force early termination use:

  

Remember to replace TASK_IDENTIFIER with the real identifier.

Final Thoughts

The BackgroundTasks framework is a great way of scheduling your heavy work with the best user experience by using environment conditions. This year WWDC was so rich, Apple released a bunch of new frameworks, and I will try to cover more new topics in the next posts. Thanks for reading!