Background Tasks Implementation for iOS App

NOVASOLUTIONS.TECHNOLOGY is engaged in the development, support and maintenance of iOS, Android, PWA mobile applications. We have extensive experience and expertise in publishing mobile applications in popular markets like Google Play, App Store, Amazon, AppGallery and others.
Development and support of all types of mobile applications:
Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1 servicesAll 1735 services
Background Tasks Implementation for iOS App
Medium
~2-3 business days
FAQ
Our competencies:
Development stages
Latest works
  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    756
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    624
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1052
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    947
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    862
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    445

Implementing Background Tasks for iOS App

iOS aggressively limits background code execution. An app that goes to background gets 30 seconds to finish current work, then is suspended. BackgroundTasks framework (iOS 13+) is the only official way to run code in background on a regular basis: data synchronization, content updates, ML inference.

Two Types of Tasks

BGAppRefreshTask — short task (30 seconds maximum). System launches it when conditions are right: device is charging or connected to Wi-Fi, user is active. Suitable for updating interface data.

BGProcessingTask — long task (minutes). Launched only when charging and on Wi-Fi. Suitable for heavy operations: database migration, large content download, CoreML model retraining.

Registration and Scheduling

In Info.plist add task identifiers to BGTaskSchedulerPermittedIdentifiers:

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.yourapp.refresh</string>
    <string>com.yourapp.processing</string>
</array>

Registration in AppDelegate before applicationDidFinishLaunching completes:

import BackgroundTasks

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

    BGTaskScheduler.shared.register(
        forTaskWithIdentifier: "com.yourapp.refresh",
        using: nil
    ) { task in
        self.handleRefresh(task: task as! BGAppRefreshTask)
    }

    BGTaskScheduler.shared.register(
        forTaskWithIdentifier: "com.yourapp.processing",
        using: nil
    ) { task in
        self.handleProcessing(task: task as! BGProcessingTask)
    }

    return true
}

Scheduling — when app transitions to background:

func scheduleAppRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "com.yourapp.refresh")
    request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60) // not earlier than 15 min
    try? BGTaskScheduler.shared.submit(request)
}

func scheduleProcessing() {
    let request = BGProcessingTaskRequest(identifier: "com.yourapp.processing")
    request.requiresNetworkConnectivity = true
    request.requiresExternalPower = true
    request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
    try? BGTaskScheduler.shared.submit(request)
}

Schedule every time when going to background via sceneDidEnterBackground or applicationDidEnterBackground. One submit call — one task submission to queue.

Task Handler

func handleRefresh(task: BGAppRefreshTask) {
    // Reschedule next execution
    scheduleAppRefresh()

    let syncTask = Task {
        do {
            try await DataSyncService.shared.sync()
            task.setTaskCompleted(success: true)
        } catch {
            task.setTaskCompleted(success: false)
        }
    }

    // Mandatory! If system takes CPU — cancel and signal
    task.expirationHandler = {
        syncTask.cancel()
        task.setTaskCompleted(success: false)
    }
}

expirationHandler is the most common mistake people skip. If you don't call setTaskCompleted before time expires, system kills the process and marks the app as abusing background execution. After several such cases, iOS stops launching the app's tasks.

When System Really Launches Tasks

Can't guarantee specific launch time — iOS decides based on usage patterns, battery, network. Apps used frequently get more background time. New or rarely used apps get less.

Debugging in Xcode: tasks can be force-launched via Xcode Debug Menu while debugging on real device:

Xcode → Debug → Simulate Background Fetch

Or via lldb:

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.yourapp.refresh"]

Simulator doesn't support BackgroundTasks — only real device.

URLSession Background Transfer

For background download and upload BackgroundTasks is not needed — use URLSessionConfiguration.background(withIdentifier:). System manages transfer itself, app gets callback on completion via AppDelegate.application(_:handleEventsForBackgroundURLSession:completionHandler:). This works even if app was unloaded from memory.

Timeline Benchmarks

Task Timeline
BGAppRefreshTask (data synchronization) 1 day
BGProcessingTask (heavy operations) 1–2 days
+ URLSession background transfer +0.5–1 day
Full background infrastructure 2–3 days