Multiple background tasks in SwiftUI

Hello fellow developers.

I'm working on adding background tasks to my SwiftUI app and running into some issues.

I have added the capabilities for background modes (fetch and processing) and the correct identifiers in "Permitted background task scheduler identifiers"

When I test the background tasks on my device, it seems to only schedule the first task and ignoring the rest.

I can run the first background task just fine with the command:

e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"spotpricesRefresh"]

But it only works for the first task since no other tasks seem to be scheduled. My code looks as below:

.onChange(of: phase) {
    if (phase == .background) {
        scheduleSpotpricesRefresh()
        scheduleEmissionsRefresh()
        scheduleSourcesRefresh()
        
        BGTaskScheduler.shared.getPendingTaskRequests(completionHandler: { request in
            print("Pending task requests: \(request)")
        })
    }
}
.backgroundTask(.appRefresh("spotpricesRefresh")) {
    await refreshSpotprices()
}
.backgroundTask(.appRefresh("emissionsRefresh")) {
    await refreshEmissions()
}
.backgroundTask(.appRefresh("sourcesRefresh")) {
    await refreshSources()
}
func scheduleSpotpricesRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "spotpricesRefresh")
    
    request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 60)
    
    do {
        try BGTaskScheduler.shared.submit(request)
        
        print("Scheduling spotprice refresh task")
    }
    catch {
        print("Could not schedule spotprices refresh: \(error)")
    }
}

func scheduleEmissionsRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "emissionsRefresh")
    
    request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 62)
    
    do {
        try BGTaskScheduler.shared.submit(request)
        
        print("Scheduling emissions refresh task")
    }
    catch {
        print("Could not schedule emissions refresh: \(error)")
    }
}

func scheduleSourcesRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "sourcesRefresh")
    
    request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 61)
    
    do {
        try BGTaskScheduler.shared.submit(request)
        
        print("Scheduling sources refresh task")
    }
    catch {
        print("Could not schedule sources refresh: \(error)")
    }
}
func refreshSpotprices() async {
    do {
        scheduleSpotpricesRefresh()
        
        ...
    }
    catch {
        print("Error occurred refreshing spotprices with error: \(error)")
    }
}

func refreshEmissions() async {
    do {
        scheduleEmissionsRefresh()
        
        ...
    }
    catch {
        print("Error occurred refreshing emissions with error: \(error)")
    }
}

func refreshSources() async {
    do {
        scheduleSourcesRefresh()
        
        ...
    }
    catch {
        print("Error occurred refreshing sources with error: \(error)")
    }
}

Here is the output when debugging the app:

Scheduling spotprice refresh task
Scheduling emissions refresh task
Scheduling sources refresh task
Pending task requests: [<BGAppRefreshTaskRequest: spotpricesRefresh, earliestBeginDate: 2023-11-14 10:24:51 +0000>]

I hope someone can point me in the right direction. Thank you in advance.

Best regards, Casper

Hello, Casper I also spent a lot of time solving a similar problem. As a result, the answer was found in the official documentation for method submit(): "There can be a total of 1(!) refresh task and 10 processing tasks scheduled at any time"

Multiple background tasks in SwiftUI
 
 
Q