You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Swift后台App刷新任务无法运行问题排查(Swift 5.7+Scene)

Swift 5.7 + Scene架构下后台HTTP接口调用异常排查

我用Swift 5.7结合Scene架构开发App,希望在App进入后台时调用HTTP接口,但当前实现无法正常工作。网上大多资源都过时了,找不到适配的示例。我通过自定义URLSessionDataDelegate实现API回调,知道要在后台任务里用dataTask(因为async/await在后台环境下无法工作),另外还想实现任务完成后自动提交新的后台任务,但这部分还没做。

目前遇到两个核心问题:

  • 猜测因为Service().callAPI()不是异步执行的,task.setTaskCompleted(success: true)会在dataTask完成前就执行,导致接口的处理逻辑没跑完就提前结束了。我尝试把BG任务传入Service,想在代理方法里调用setTaskCompleted,但没成功。
  • 频繁出现错误:NSURLErrorDomain Code=-997 "Lost connection to background transfer service"

当前代码实现

AppDelegate.swift

let bgTaskIdentifier = "task.identifier"

class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        BGTaskScheduler.shared.register(forTaskWithIdentifier: bgTaskIdentifier, using: nil) { task in
            self.handleAppRefresh(task as! BGAppRefreshTask)
        }
        print("Registered background task (\(bgTaskIdentifier))")
        return true
    }
    
    func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
        return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
    }
    
    func handleAppRefresh(_ task: BGAppRefreshTask) {
        task.expirationHandler = {
            task.setTaskCompleted(success: false)
        }
        Service().callAPI()
        task.setTaskCompleted(success: true)
    }
    
}

SceneDelegate.swift

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
    var window: UIWindow?
    
    func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
        guard let _ = (scene as? UIWindowScene) else {
            return
        }
    }
    
    func sceneDidEnterBackground(_ scene: UIScene) {
        submitBackgroundTask()
    }
    
    func submitBackgroundTask() {
        do {
            let taskRequest = BGAppRefreshTaskRequest(identifier: bgTaskIdentifier)
            taskRequest.earliestBeginDate = Date(timeIntervalSinceNow: 10)
            try BGTaskScheduler.shared.submit(taskRequest)
            logger.info("Submitted background task request")
        } catch {
            logger.info("Failed to submit task request")
        }
    }
}

Service.swift

class Service: NSObject, URLSessionDataDelegate {    
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
        let decoder = JSONDecoder()
        // Decode here and do stuff with response data
    }
    
    func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) {
        guard let response = response as? HTTPURLResponse, (200...299).contains(response.statusCode) else {
            logger.info("Request failed")
            completionHandler(.cancel)
            return
        }
        completionHandler(.allow)
    }
    
    func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
        if error != nil {
            logger.info("Failed: \(error!)")
        }
    }
    
    func callAPI() {
        let url = URL(string: "https://example.com")!
        var request = URLRequest(url: url)
        let config = URLSessionConfiguration.background(withIdentifier: bgTaskIdentifier)
        let session = URLSession(configuration: config, delegate: self, delegateQueue: nil)
        session.dataTask(with: request).resume()
    }
}

内容的提问来源于stack exchange,提问作者Mega

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 07:07:19