Popular Searches
Popular Course Categories
Popular Courses

Scheduling Background Refresh and Processing Tasks

Scheduling Background Refresh and Processing Tasks

Background Tasks, Push Notifications, and App Services

Scheduling Background Refresh and Processing Tasks in iOS

Course: iOS App Development

Topic: Scheduling Background Refresh and Processing Tasks

Course Link: iOS App Development Training

Demo Link: Register for Course Demo

Website: JustAcademy


1. Introduction to Background Tasks in iOS

Background tasks allow an iOS application to perform selected operations when it is not actively visible to the user. These operations may include refreshing application content, synchronizing data, cleaning databases, downloading information, and processing files.

iOS controls background execution to protect battery life, device performance, and user privacy. Developers cannot assume that an application will run continuously after it enters the background. Instead, they must use Apple's supported background execution APIs and allow the operating system to decide when scheduled work can run.

The BackgroundTasks framework provides APIs for scheduling and managing background work.

Learning Objectives

  • Understand how background execution works in iOS.
  • Differentiate between BGAppRefreshTask and BGProcessingTask.
  • Configure Background Modes in Xcode.
  • Register background task identifiers.
  • Schedule background refresh and processing requests.
  • Handle task expiration and completion correctly.
  • Test and troubleshoot background tasks.

2. Understanding iOS Application Lifecycle and Background Execution

An iOS application moves between different lifecycle states depending on user interaction and system activity.

Application State Description
Not Running The application has not been launched or has been terminated.
Inactive The application is temporarily not receiving user events.
Active The application is running in the foreground and interacting with the user.
Background The application is not visible but may receive limited execution time.
Suspended The application remains in memory but does not execute code.

When an application enters the background, iOS may suspend it shortly afterward. Scheduled background tasks provide an opportunity for the system to launch the application and execute approved work at a suitable time.

3. Introduction to the BackgroundTasks Framework

The BackgroundTasks framework allows developers to register, schedule, and execute background operations using system-managed task requests.

Important classes include:

Class Purpose
BGTaskScheduler Registers task handlers and submits background task requests.
BGTask Base class representing a background task.
BGAppRefreshTask Handles short background content refresh operations.
BGProcessingTask Handles longer processing and maintenance operations.
BGAppRefreshTaskRequest Creates a request for a short refresh task.
BGProcessingTaskRequest Creates a request for a longer processing task.

4. Difference Between BGAppRefreshTask and BGProcessingTask

iOS provides different task types depending on the amount and nature of background work required.

Feature BGAppRefreshTask BGProcessingTask
Purpose Refresh application content. Perform longer processing operations.
Execution Short background execution. Can run for minutes when conditions permit.
Typical Use Fetching recent news or updating dashboard data. Database maintenance, synchronization, and file processing.
System Control System decides when to launch the task. System chooses a suitable processing window.
Power Requirements Does not provide a charger requirement option. Can request external power.
Network Requirements Does not provide the same processing-request network constraints. Can request network connectivity.
Execution Guarantee No guaranteed schedule. No guaranteed schedule.

Important: Setting an earliest begin date does not guarantee that a task will run at that exact time. The operating system makes the final scheduling decision.

5. Configuring Background Modes in Xcode

Before scheduling background tasks, enable the appropriate capabilities in the application target.

Configuration Steps

  1. Open the iOS project in Xcode.
  2. Select the application target.
  3. Open the Signing & Capabilities tab.
  4. Click the + Capability button if Background Modes is not already available.
  5. Add Background Modes.
  6. Enable Background fetch for refresh operations.
  7. Enable Background processing for processing operations.
  8. Verify that the application's configuration matches the task types used in the code.

Only enable the background modes that the application genuinely requires. Unnecessary background capabilities should be avoided.

6. Configuring BGTaskSchedulerPermittedIdentifiers

Every scheduled task must use a unique identifier. These identifiers must be declared in the application's Info.plist file using the BGTaskSchedulerPermittedIdentifiers key.

Example Info.plist Configuration

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.example.iosapp.refresh</string>
    <string>com.example.iosapp.processing</string>
</array>

Each identifier must match the identifier used during registration and scheduling. If an identifier is missing or incorrectly written, task submission may fail with a not-permitted error.

Note: When using the BackgroundTasks framework with this permitted-identifier configuration, the older background-fetch methods application(_:performFetchWithCompletionHandler:) and setMinimumBackgroundFetchInterval(_:) are disabled for that application configuration on iOS 13 and later.

7. Importing the BackgroundTasks Framework

Import the framework in the Swift file where background tasks are registered and scheduled.

import UIKit
import BackgroundTasks

The BackgroundTasks module provides the scheduler, task requests, and task objects required for background execution.

8. Registering a Background Refresh Task

Registration connects a unique task identifier with a handler that executes when iOS launches the application to perform the task.

import UIKit
import BackgroundTasks

final class BackgroundTaskManager {
    static let shared = BackgroundTaskManager()

    let refreshIdentifier = "com.example.iosapp.refresh"

    private init() {}

    func registerTasks() {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: refreshIdentifier,
            using: nil
        ) { task in
            guard let refreshTask = task as? BGAppRefreshTask else {
                task.setTaskCompleted(success: false)
                return
            }

            self.handleAppRefresh(task: refreshTask)
        }
    }

    private func handleAppRefresh(task: BGAppRefreshTask) {
        print("Background refresh task started")

        task.setTaskCompleted(success: true)
    }
}

The registration method should be called during application launch, before the launch sequence finishes. Register every task identifier that the application intends to schedule.

9. Scheduling a BGAppRefreshTask

After registration, create a BGAppRefreshTaskRequest and submit it to the shared task scheduler.

func scheduleAppRefresh() {
    let request = BGAppRefreshTaskRequest(
        identifier: "com.example.iosapp.refresh"
    )

    request.earliestBeginDate =
        Date(timeIntervalSinceNow: 15 * 60)

    do {
        try BGTaskScheduler.shared.submit(request)
        print("Refresh task scheduled")
    } catch {
        print("Unable to schedule refresh task: \(error)")
    }
}

Understanding earliestBeginDate

The earliestBeginDate property specifies the earliest time at which the system may begin the task. It does not specify an exact execution time.

  • Date() represents the current date and time.
  • TimeIntervalSinceNow: 15 * 60 represents 15 minutes from the current time.
  • The system may run the task later depending on device conditions and scheduling priorities.
  • The task may not run if the user force-quits the application or system conditions prevent execution.

10. Handling Background Refresh Operations

A refresh task is useful when the application needs to retrieve small amounts of updated information from a remote server or update local application data.

Example: Refreshing Application Content

func handleAppRefresh(task: BGAppRefreshTask) {
    scheduleAppRefresh()

    let queue = OperationQueue()

    let operation = BlockOperation {
        print("Fetching latest application data")
        // Perform a short refresh operation here.
    }

    task.expirationHandler = {
        queue.cancelAllOperations()
    }

    operation.completionBlock = {
        let success = !operation.isCancelled
        task.setTaskCompleted(success: success)
    }

    queue.addOperation(operation)
}

This example schedules another refresh request and performs a short operation. In a production application, the operation should handle network errors, data validation, cancellation, and persistence appropriately.

11. Registering a BGProcessingTask

A processing task is designed for work that requires more time than a typical content refresh. Examples include database cleanup, large data synchronization, and preparing locally stored information.

final class BackgroundTaskManager {
    static let shared = BackgroundTaskManager()

    let processingIdentifier = "com.example.iosapp.processing"

    func registerProcessingTask() {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: processingIdentifier,
            using: nil
        ) { task in
            guard let processingTask = task as? BGProcessingTask else {
                task.setTaskCompleted(success: false)
                return
            }

            self.handleProcessingTask(task: processingTask)
        }
    }

    func handleProcessingTask(task: BGProcessingTask) {
        print("Background processing started")

        task.expirationHandler = {
            print("Processing task is expiring")
        }

        // Start the processing operation here.
        task.setTaskCompleted(success: true)
    }
}

The sample demonstrates the registration and lifecycle structure. Real processing work must finish before reporting success. Do not mark a task completed immediately while asynchronous work is still running.

12. Scheduling a BGProcessingTask

Use BGProcessingTaskRequest to schedule a processing operation.

func scheduleProcessingTask() {
    let request = BGProcessingTaskRequest(
        identifier: "com.example.iosapp.processing"
    )

    request.requiresNetworkConnectivity = true
    request.requiresExternalPower = true

    request.earliestBeginDate =
        Date(timeIntervalSinceNow: 60 * 60)

    do {
        try BGTaskScheduler.shared.submit(request)
        print("Processing task scheduled")
    } catch {
        print("Processing task scheduling failed: \(error)")
    }
}

Important Request Properties

Property Purpose
identifier Identifies the registered processing task.
earliestBeginDate Specifies the earliest permitted start time.
requiresNetworkConnectivity Requests network connectivity before execution.
requiresExternalPower Requests execution when external power is available.

These properties express the application's requirements. They do not force iOS to execute the task at a particular time.

13. Handling Task Expiration

iOS can interrupt a background task when the allocated execution time expires or system conditions change. Developers must use the expirationHandler to cancel ongoing work and preserve application consistency.

func handleProcessingTask(task: BGProcessingTask) {
    let operation = BlockOperation {
        print("Performing database maintenance")
        // Perform cancellable maintenance work.
    }

    let queue = OperationQueue()
    queue.addOperation(operation)

    task.expirationHandler = {
        operation.cancel()
    }

    operation.completionBlock = {
        let success = !operation.isCancelled
        task.setTaskCompleted(success: success)
    }
}

Why Expiration Handling Matters

  • Prevents unnecessary processing after the system ends the task.
  • Reduces the risk of incomplete database operations.
  • Allows cancellable network or file operations to stop safely.
  • Helps the application preserve its data before suspension.

14. Completing Background Tasks Correctly

Every background task must report its completion using setTaskCompleted(success:).

task.setTaskCompleted(success: true)

Use true when the intended operation finishes successfully. Use false when the operation fails or is cancelled before completion.

For asynchronous operations, call the completion method only after the actual work has finished. Ensure that completion is reported exactly once for each task execution.

15. Registering Tasks During Application Launch

Task handlers must be registered early in the application launch sequence. For a UIKit application, registration can be performed in the application delegate.

import UIKit
import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {

    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions:
        [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {

        BackgroundTaskManager.shared.registerTasks()

        return true
    }
}

Register all required handlers before the end of the launch sequence so the system can locate the correct handler when launching the application for background work.

16. Rescheduling Tasks After Execution

Scheduled background requests are not automatically recurring. If an application needs future refreshes, it should submit another request as part of its task-handling workflow.

func handleAppRefresh(task: BGAppRefreshTask) {
    // Schedule the next refresh request.
    scheduleAppRefresh()

    // Perform the current refresh operation.
    performRefresh { success in
        task.setTaskCompleted(success: success)
    }
}

The example assumes that performRefresh is an application-defined asynchronous method. The next request should be scheduled according to the application's actual refresh needs.

17. Managing Network Operations in Background Tasks

Applications frequently use background tasks to retrieve updated information from APIs. Network operations should include timeouts, error handling, and cancellation support.

func fetchLatestData(
    completion: @escaping (Bool) -> Void
) {
    guard let url = URL(
        string: "https://api.example.com/data"
    ) else {
        completion(false)
        return
    }

    URLSession.shared.dataTask(with: url) {
        data, response, error in

        guard error == nil,
              let data = data,
              let response = response as? HTTPURLResponse,
              (200...299).contains(response.statusCode)
        else {
            completion(false)
            return
        }

        // Decode and save the received data.
        print("Received \(data.count) bytes")
        completion(true)
    }.resume()
}

For downloads or uploads that must continue independently of the application's ordinary execution time, consider a background-configured URLSession. A scheduled background task and a background URL session solve different problems and can be used together when appropriate.

18. Choosing the Correct Background Execution Strategy

Not every background operation should use BGAppRefreshTask or BGProcessingTask. Select the API based on the application's requirements.

Requirement Recommended Approach
Fetch small updates at a system-selected time BGAppRefreshTask
Perform deferred database maintenance BGProcessingTask
Continue a critical operation briefly after entering background beginBackgroundTask(withName:expirationHandler:)
Transfer large files while the app is not active Background URLSession
Wake the app when a server reports new content Background push notifications, when appropriate
Continue a user-started supported long-running job after the app backgrounds BGContinuedProcessingTask on supported iOS versions

Use the simplest supported strategy that matches the required behavior. Background execution is system-managed and is never a substitute for a guaranteed always-running service.

19. Background Push Notifications and Scheduled Refresh

Background push notifications allow a server to notify an application that new content may be available. The system may wake the application so it can retrieve that content.

A background push commonly uses the content-available field in the APNs payload.

{
    "aps": {
        "content-available": 1
    }
}

Background pushes are discretionary and are not guaranteed to arrive or execute immediately. They are different from user-visible notifications, which may include an alert, sound, or badge.

20. Background Task Testing and Debugging

Background tasks may not run at predictable intervals during ordinary testing. Developers should use Xcode and supported debugging methods to simulate task execution.

Testing Checklist

  1. Verify the Background Modes capability.
  2. Confirm that the task identifier exists in Info.plist.
  3. Check that the identifier matches the registration code exactly.
  4. Confirm that registration occurs during application launch.
  5. Verify that task submission does not throw an error.
  6. Test successful execution and task expiration.
  7. Test network failures and cancellation.
  8. Confirm that completion is reported correctly.
  9. Test on physical devices under different battery and network conditions.

During development, Xcode's debugging facilities can be used to simulate launching and expiration of supported background tasks. Such simulation helps test handlers but does not guarantee the same scheduling behavior in production.

21. Common Background Task Errors and Solutions

Problem Possible Cause Solution
Task submission fails Identifier is not permitted. Add the exact identifier to BGTaskSchedulerPermittedIdentifiers.
Handler is not called Task was not registered correctly. Register the handler during application launch.
Task does not run at expected time System controls scheduling. Do not depend on exact execution times.
Processing task does not execute Required Background Mode is missing. Enable Background processing and verify request conditions.
Task is interrupted Execution time expires or system conditions change. Use expiration handling and make work resumable.
Data is incomplete Operation was interrupted before saving. Use safe checkpoints and atomic persistence where suitable.
Repeated submissions fail Invalid request or scheduling constraints. Inspect the thrown error and review the request configuration.
Task reports success too early Completion is called before asynchronous work finishes. Report completion from the actual operation's completion callback.

22. Best Practices for Background Task Scheduling

  • Use BGAppRefreshTask for short refresh operations.
  • Use BGProcessingTask for deferred, intensive processing.
  • Register task handlers early during application launch.
  • Use unique and descriptive task identifiers.
  • Declare every permitted identifier in Info.plist.
  • Enable only the necessary background capabilities.
  • Set earliestBeginDate according to actual application requirements.
  • Never assume that a task will execute at an exact time.
  • Implement expiration handlers for cancellable work.
  • Save progress periodically for operations that may be interrupted.
  • Use background URLSession for suitable file-transfer requirements.
  • Handle network failures and offline conditions.
  • Call setTaskCompleted(success:) after the operation finishes.
  • Monitor battery usage and avoid unnecessary background activity.
  • Test on physical devices and under different system conditions.

23. Practical Project: Background Data Refresh and Database Maintenance

Project Objective: Build an iOS application that schedules a short content refresh and a separate database maintenance task.

Project Features

  • Register a background refresh task.
  • Register a background processing task.
  • Schedule refresh requests for updated server data.
  • Schedule processing requests for database cleanup.
  • Handle task expiration and cancellation.
  • Store the last successful refresh time.
  • Display the latest available data when the user opens the app.

Step 1: Define Task Identifiers

let refreshTaskID = "com.example.iosapp.refresh"
let cleanupTaskID = "com.example.iosapp.cleanup"

Step 2: Register Both Task Handlers

func registerBackgroundTasks() {
    BGTaskScheduler.shared.register(
        forTaskWithIdentifier: refreshTaskID,
        using: nil
    ) { task in
        guard let task = task as? BGAppRefreshTask else {
            task.setTaskCompleted(success: false)
            return
        }

        self.handleRefresh(task)
    }

    BGTaskScheduler.shared.register(
        forTaskWithIdentifier: cleanupTaskID,
        using: nil
    ) { task in
        guard let task = task as? BGProcessingTask else {
            task.setTaskCompleted(success: false)
            return
        }

        self.handleCleanup(task)
    }
}

Step 3: Schedule Both Tasks

func scheduleBackgroundTasks() {
    let refreshRequest = BGAppRefreshTaskRequest(
        identifier: refreshTaskID
    )
    refreshRequest.earliestBeginDate =
        Date(timeIntervalSinceNow: 30 * 60)

    let cleanupRequest = BGProcessingTaskRequest(
        identifier: cleanupTaskID
    )
    cleanupRequest.requiresNetworkConnectivity = false
    cleanupRequest.requiresExternalPower = true

    do {
        try BGTaskScheduler.shared.submit(refreshRequest)
        try BGTaskScheduler.shared.submit(cleanupRequest)
        print("Background requests submitted")
    } catch {
        print("Scheduling error: \(error)")
    }
}

Step 4: Implement Task Handlers

func handleRefresh(_ task: BGAppRefreshTask) {
    scheduleRefreshAgain()

    let operation = createRefreshOperation()
    let queue = OperationQueue()

    task.expirationHandler = {
        operation.cancel()
    }

    operation.completionBlock = {
        task.setTaskCompleted(
            success: !operation.isCancelled
        )
    }

    queue.addOperation(operation)
}

func handleCleanup(_ task: BGProcessingTask) {
    let operation = createCleanupOperation()
    let queue = OperationQueue()

    task.expirationHandler = {
        operation.cancel()
    }

    operation.completionBlock = {
        task.setTaskCompleted(
            success: !operation.isCancelled
        )
    }

    queue.addOperation(operation)
}

Implementation note: The methods scheduleRefreshAgain(), createRefreshOperation(), and createCleanupOperation() represent application-specific methods that must be implemented. The task identifiers must also be added to Info.plist, and the corresponding Background Modes must be enabled.

Expected Result

The application can request short content refreshes and deferred database maintenance. iOS decides when these requests can execute. The application handles interruptions safely and displays the latest successfully saved information when the user returns.

24. Practice Exercises

  1. Create an iOS project and enable Background Modes.
  2. Register a BGAppRefreshTask using a unique identifier.
  3. Schedule a refresh request with an earliest begin date.
  4. Create a BGProcessingTask for database cleanup.
  5. Configure external power and network requirements.
  6. Implement an expiration handler using OperationQueue.
  7. Save a timestamp after successful background refresh.
  8. Test task registration and submission errors.
  9. Compare background URLSession with BGProcessingTask.
  10. Build a small application that refreshes and displays remote data.

25. Interview Questions and Answers

Q1. What is background execution in iOS?

Answer: Background execution allows an iOS application to perform approved work when it is not visible to the user, subject to operating-system scheduling and execution limits.

Q2. What is the BackgroundTasks framework?

Answer: It is an Apple framework used to register, schedule, and execute system-managed background tasks.

Q3. What is BGAppRefreshTask?

Answer: BGAppRefreshTask is used for short background operations such as retrieving updated content from a server.

Q4. What is BGProcessingTask?

Answer: BGProcessingTask is used for longer deferred operations such as database maintenance, synchronization, and data processing.

Q5. What is BGTaskScheduler?

Answer: BGTaskScheduler registers task handlers and submits background task requests to iOS.

Q6. What is earliestBeginDate?

Answer: It specifies the earliest time at which a scheduled task may begin. It does not guarantee execution at that time.

Q7. Why is BGTaskSchedulerPermittedIdentifiers required?

Answer: It declares the task identifiers that the application is allowed to register and schedule.

Q8. What is an expiration handler?

Answer: It is a closure called when the system needs the task to stop. Developers should cancel ongoing work and perform necessary cleanup.

Q9. How does an application report task completion?

Answer: It calls setTaskCompleted(success:) after the actual operation finishes.

Q10. Does iOS guarantee background task execution?

Answer: No. The operating system decides when a task can run based on system conditions, resource availability, and scheduling policies.

Q11. Why should task handlers be registered during application launch?

Answer: The system needs to find the correct handler when it launches the application to execute a scheduled task.

Q12. When should developers use background URLSession?

Answer: It is appropriate for file downloads and uploads that need to continue under system-managed transfer execution when the application is not active.

26. Quick Revision Checklist

  • Understand the iOS application lifecycle.
  • Know the purpose of the BackgroundTasks framework.
  • Differentiate BGAppRefreshTask and BGProcessingTask.
  • Enable the correct Background Modes.
  • Configure BGTaskSchedulerPermittedIdentifiers.
  • Register task handlers during application launch.
  • Submit requests through BGTaskScheduler.
  • Understand earliestBeginDate.
  • Handle task expiration and cancellation.
  • Call setTaskCompleted(success:) after work finishes.
  • Use the appropriate API for network transfers and other background work.
  • Test background execution without assuming exact scheduling times.

27. Conclusion

Scheduling background refresh and processing tasks is an important part of building reliable iOS applications. The BackgroundTasks framework provides BGAppRefreshTask for short content updates and BGProcessingTask for longer maintenance and processing operations.

Successful implementation requires correct task registration, permitted identifiers, appropriate background capabilities, request scheduling, expiration handling, and accurate completion reporting. Developers should design background operations to be efficient, cancellable, and safe to resume because iOS controls when background execution is available.

28. Additional Learning Resources

Previous Next
whatsapp