iOS Background Work

iOS Background Work

When a user minimizes your app to the Home Screen, iOS suspends it almost immediately.

Suspended apps cannot execute code, make network requests, or update data.

However, iOS provides the BackgroundTasks framework to schedule specific jobs to run quietly in the background when the device is idle.


The BGTaskScheduler

To run a task in the background, you must register a unique identifier in your Info.plist file.

Then, you use BGTaskScheduler to tell the system you have work that needs to be done.

iOS will intelligently decide the best time to wake your app up to run the task, usually when the phone is charging and connected to Wi-Fi.

Registering a Background Task:

import BackgroundTasks
import UIKit

class AppDelegate: UIResponder, UIApplicationDelegate { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { // Register the task identifier that matches your Info.plist BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.intricatedevo.refresh", using: nil) { task in // This block is what actually runs in the background! self.handleAppRefresh(task: task as! BGAppRefreshTask) } return true } func handleAppRefresh(task: BGAppRefreshTask) { // Perform your database cleanup or network fetch here // Inform the system when you are finished task.setTaskCompleted(success: true) } }


Scheduling the Task

Registering the task isn't enough; you must also explicitly schedule it before your app goes to sleep.

You create a BGAppRefreshTaskRequest, set an earliest begin date, and submit it to the scheduler.

Scheduling the Request:

func scheduleAppRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "com.intricatedevo.refresh")
    // Tell iOS not to run this for at least 15 minutes
    request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
    do {
        try BGTaskScheduler.shared.submit(request)
        print("Background task scheduled successfully.")
    } catch {
        print("Could not schedule app refresh: \\(error)")
    }
}

Handling Expiration

Background tasks have a strict time limit (usually around 30 seconds).

If your task takes too long, iOS will forcefully kill your app.

You must always set the task.expirationHandler closure. If iOS decides it's time to cut you off, this closure will fire, giving you one last chance to save data and cleanly exit.


Silent Push Notifications

Another way to trigger background work is using Silent Push Notifications.

Your server can send a special notification to the device that wakes the app in the background, allowing it to download fresh content before the user even opens the app!


Exercise

If your background task takes too long to complete, what will the iOS system do?