'BGAppRefreshTask not executing SwiftUI
I'm getting inconsistent results when using the Background Tasks framework for my application written in SwiftUI. I'm only looking to make quick network requests, so I'm choosing to use BGAppRefreshTask.
Background fetch, and Background Processing are set in Signing & Capabilities. Permitted background task scheduler identifiers have been set. Manually calling it in debugging works fine on a real device but never in production.
I tested both BGAppRefreshTask, and BGProcessingTask. I noticed BGProcessingTask is being called but only when connected to a power supply. I never see any updates from BGAppRefreshTask. I'm not sure if I'm missing something simple.
BGAppRefreshTask hasn't run for FOUR days now since updating this post. BGProcessingTask was run 13 time's overnight but only if my device is charging. Even when setting requiresExternalPower to false.
BGAppRefreshTask run: 0 & BGProcessingTask run: 13
Calling in the debugger using commands here works but it's never run on my device without simulating in the debugger.
(lldb) e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.bgapp.refresh"]
2022-02-26 11:41:33.964753-0800 BGAppRefreshTask[9180:2203525] Simulating launch for task with identifier com.bgapp.refresh
2022-02-26 11:41:35.908739-0800 BGAppRefreshTask[9180:2203542] Starting simulated task: <decode: missing data>
2022-02-26 11:41:35.912108-0800 BGAppRefreshTask[9180:2203542] Marking simulated task complete: <BGAppRefreshTask: com.bgapp.refresh>
Received completion: finished.
UPDATE
I used getPendingTaskRequests to see if any task was being registered and it's apparent it is but still not executing. The earliest date is scheduled for 19:28 so 7:28PM. I registered my task at 11:23AM but it's not schedule to run for another 8 hours.
Pending task requests: [<BGAppRefreshTaskRequest: com.bgapp.refresh, earliestBeginDate: 2022-02-28 19:28:34 +0000>]
BGAppRefresh
/*!
BGAppRefreshTask
@abstract A background task used to update your app's contents in the background.
*/
class BGADelegate: NSObject, UIApplicationDelegate, ObservableObject {
let taskIdentifier = "com.bgapp.refresh"
@AppStorage("backgroundtask") var tasks: Int = 0
func application(_ applicatiown: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
register()
scheduleAppRefresh()
return true
}
func register() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: taskIdentifier, using: nil) { task in
self.handleAppRefresh(task: task as! BGAppRefreshTask)
print("register")
}
}
func scheduleAppRefresh() {
let request = BGAppRefreshTaskRequest(identifier: taskIdentifier)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
func handleAppRefresh(task: BGAppRefreshTask) {
scheduleAppRefresh()
task.expirationHandler = {
task.setTaskCompleted(success: false)
}
DispatchQueue.main.async {
self.tasks += 1
}
// Network request here
task.setTaskCompleted(success: true)
print("handle app refresh")
}
}
BGProcessingTask
/*!
BGProcessingTask
@abstract A background task used to perform deferrable processing.
*/
class BGPDelegate: NSObject, UIApplicationDelegate, ObservableObject {
let taskIdentifier = "com.bgapp.refresh"
@AppStorage("backgroundtask") var tasks: Int = 0
func application(_ applicatiown: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
register()
scheduleAppRefresh()
return true
}
func register() {
BGTaskScheduler.shared.register(forTaskWithIdentifier: taskIdentifier, using: nil) { task in
self.handleAppRefresh(task: task as! BGProcessingTask)
print("register")
}
}
func scheduleAppRefresh() {
let request = BGProcessingTaskRequest(identifier: taskIdentifier)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
request.requiresNetworkConnectivity = true
request.requiresExternalPower = false // Default value in false
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("Could not schedule app refresh: \(error)")
}
}
func handleAppRefresh(task: BGProcessingTask) {
scheduleAppRefresh()
task.expirationHandler = {
task.setTaskCompleted(success: false)
}
DispatchQueue.main.async {
self.backgroundtask += 1
}
// Network request here
task.setTaskCompleted(success: true)
print("handle app refresh")
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
