Class

BGTaskScheduler

A class for scheduling tasks run by submitting task requests that launch your app in the background.

Declaration

class BGTaskScheduler : NSObject

Overview

A task is a standalone activity, such as cleaning a database, updating a machine learning model, or updating the displayed data for an app. To make efficient use of processing time and power, the system can launch your app in the background to run tasks like these when the device isn’t in use.

A task can run many times and requires:

  • Configuring the app to enable background task execution.

  • Registering a launch handler for the task.

  • Scheduling the task.

Configuring the App for Background Tasks

Configure the app for background tasks by adding the capabilities for the required background modes, and by adding a whitelist of task identifiers.

To add the capabilities:

  • Open the project editor and select the desired target.

  • Click Signing & Capabilities.

  • Expand the Background Modes section. If there’s no Background Modes section, click the “+ Capability” button and choose Background Modes in the window that appears.

  • Select one or both of Background fetch and Background processing based on the needs of your background tasks.

The Xcode project editor showing the Background Modes capabilities editor of the Signing & Capabilities pane. A text callout points to the "+ Capability" button at the top-left above the editors and another callout identifies the two background mode checkbox items.

The system runs only tasks registered with identifiers on a whitelist of task identifiers. To add the whitelist, add the identifiers to the Info.plist file (The Info.plist File):

  • Open the Project navigator and select the desired target.

  • Click Info and expand Custom iOS Target Properties.

  • Add a new item to the list and choose “Permitted background task scheduler identifiers,” which corresponds to the BGTaskSchedulerPermittedIdentifiers array.

  • Add the string for each authorized task identifier as a separate item in the array.

Illustration showing the Custom iOS Target Properties editor of the Info pane. A box is drawn around the example entries in the "Permitted background task schedule identifiers" array, which shows two identifiers. Item 0 is refresh, item 1 is .db_cleaning.

Adding a BGTaskSchedulerPermittedIdentifiers key to the Info.plist disables application(_:performFetchWithCompletionHandler:) and setMinimumBackgroundFetchInterval(_:) in iOS 13 and later.

Registering, Scheduling, and Running Tasks

During app startup, you register a launch handler, a small block of code that runs the task, and an associated unique identifier for each task. Register all of the tasks before the end of the app launch sequence. For more information, see About the App Launch Sequence.

Flow diagram showing when a task object is run. The flow starts with app launch, after which the task is scheduled, run, and completed.

The following code registers a handler, handleAppRefresh(task:), that's called when the system runs a task request with the identifier com.example.apple-samplecode.ColorFeed.refresh.

BGTaskScheduler.shared.register(forTaskWithIdentifier:
   "com.example.apple-samplecode.ColorFeed.refresh",
   using: nil)
     {task in
        self.handleAppRefresh(task: task as! BGAppRefreshTask)
     }

Submit a task request for the system to launch your app in the background at a later time using submit(_:). Submitting a task again replaces the previous submission. For example, updating a task's settings requires resubmitting the task.

The code below schedules a refresh task request for the previously registered com.example.apple-samplecode.ColorFeed.refresh task identifier.

func scheduleAppRefresh() {
   let request = BGAppRefreshTaskRequest(identifier: "com.example.apple-samplecode.ColorFeed.refresh")
   // Fetch no earlier than 15 minutes from now
   request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
        
   do {
      try BGTaskScheduler.shared.submit(request)
   } catch {
      print("Could not schedule app refresh: \(error)")
   }
}

When the system opens your app in the background, it calls the launch handler to run the task.

func handleAppRefresh(task: BGAppRefreshTask) {
   // Schedule a new refresh task
   scheduleAppRefresh()

   // Create an operation that performs the main part of the background task
   let operation = RefreshAppContentsOperation()
   
   // Provide an expiration handler for the background task
   // that cancels the operation
   task.expirationHandler = {
      operation.cancel()
   }

   // Inform the system that the background task is complete
   // when the operation completes
   operation.completionBlock = {
      task.setTaskCompleted(success: !operation.isCancelled)
   }

   // Start the operation
   operationQueue.addOperation(operation)
 }

Your task provides an expiration handler that the system calls if it needs to terminate your task. You also add code to inform the system if the task completes successfully.

Registering and Scheduling Tasks in Extensions

Extensions can schedule a task, such as the update of a machine learning model. Register a task scheduled by extensions in the main app. The system launches the app to run the task.

Topics

Getting the Shared Task Scheduler

class var shared: BGTaskScheduler

The shared background task scheduler instance.

Scheduling a Task

func register(forTaskWithIdentifier: String, using: DispatchQueue?, launchHandler: (BGTask) -> Void) -> Bool

Register a launch handler for the task with the associated identifier that’s executed on the specified queue.

func submit(BGTaskRequest)

Submit a previously registered background task for execution.

Canceling a Task

func cancel(taskRequestWithIdentifier: String)

Cancel a previously scheduled task request.

func cancelAllTaskRequests()

Cancel all scheduled task requests.

Getting All Scheduled Tasks

func getPendingTaskRequests(completionHandler: ([BGTaskRequest]) -> Void)

Request a list of unexecuted scheduled task requests.

Errors

struct BGTaskScheduler.Error

The Errors for the BGTaskSchedulerError domain.

class let errorDomain: String

The background tasks error domain as a string.

Relationships

Inherits From

Conforms To

See Also

Essentials

Starting and Terminating Tasks During Development

Use the debugger during development to start tasks and to terminate them before completion.

Refreshing and Maintaining Your App Using Background Tasks

Use scheduled background tasks for refreshing your app content and for performing maintenance.