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

后台应用刷新关闭时未抛出BGTaskSchedulerErrorCodeUnavailable异常

iOS BGAppRefreshTask 无法捕获后台刷新关闭时的异常问题

问题描述

我们在iOS Swift项目中实现了BGAppRefreshTask,当设备的后台应用刷新功能关闭时,执行try BGTaskScheduler.shared.submit(request)代码并未抛出预期的BGTaskSchedulerErrorCodeUnavailable异常,但该功能在后台应用刷新开启时可正常工作。测试环境为实体设备iPhone 14(iOS 18.1),需要捕获该错误用于日志记录。

示例代码

func scene(_ scene: UIScene,
           willConnectTo session: UISceneSession,
           options connectionOptions: UIScene.ConnectionOptions) {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: "com.example.bgTaskIdentifier",
                                                       using: nil) { task in
        self.handleAppRefresh(task: task as! BGAppRefreshTask)
    }
}


func sceneDidEnterBackground(_ scene: UIScene) {
    scheduleAppRefresh()
    print("Entered Background") // Prints "Entered Background"
}

func scheduleAppRefresh() {
    let request = BGAppRefreshTaskRequest(identifier: "com.example.bgTaskIdentifier")
    request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60)
    
    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        // This catch block is not executed even when background app refresh is disabled in settings.
        print("Could not schedule app refresh: \(error)")
    }
}

解决方案

1. 主动检查后台刷新状态

BGTaskScheduler.submit()在单应用关闭后台刷新时不会主动抛出异常,需要手动检查当前应用的后台刷新权限状态:

func scheduleAppRefresh() {
    // 先检查后台应用刷新是否可用
    guard UIApplication.shared.backgroundRefreshStatus == .available else {
        let error = NSError(domain: BGTaskSchedulerErrorDomain, code: BGTaskSchedulerErrorCode.unavailable.rawValue, userInfo: [NSLocalizedDescriptionKey: "Background app refresh is disabled"])
        print("Could not schedule app refresh: \(error)")
        return
    }
    
    let request = BGAppRefreshTaskRequest(identifier: "com.example.bgTaskIdentifier")
    request.earliestBeginDate = Date(timeIntervalSinceNow: 5 * 60)
    
    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        print("Could not schedule app refresh: \(error)")
    }
}

2. 理解系统行为差异

iOS 13+之后,BGTaskScheduler.submit()的错误抛出逻辑有明确区分:

  • 仅当系统层面完全禁止所有应用的后台任务调度时,才会抛出BGTaskSchedulerErrorCodeUnavailable
  • 单应用关闭后台刷新时,submit操作会返回成功,但系统不会触发后续的任务执行

3. 监听权限变化

如果需要实时感知后台刷新权限的变更,可以注册通知:

func setupBackgroundRefreshObserver() {
    NotificationCenter.default.addObserver(self, selector: #selector(handleBackgroundRefreshStatusChanged), name: UIApplication.backgroundRefreshStatusDidChangeNotification, object: nil)
}

@objc func handleBackgroundRefreshStatusChanged() {
    let status = UIApplication.shared.backgroundRefreshStatus
    switch status {
    case .available:
        print("Background refresh enabled, rescheduling tasks")
        scheduleAppRefresh()
    case .denied, .restricted:
        print("Background refresh disabled, canceling scheduled tasks")
        BGTaskScheduler.shared.cancelAllTaskRequests()
    @unknown default:
        break
    }
}

验证注意事项

  • 必须在实体设备上测试,模拟器的后台刷新行为可能与真机不一致
  • 测试时需确保应用已退出前台,后台刷新状态变更后需重新进入后台触发调度逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 04:40:07