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

Swift 6+iOS18调度后台刷新任务时应用崩溃求助

Swift 6 + iOS 18 下 BGTaskScheduler.getPendingTaskRequests 崩溃解决建议

问题重现

在Swift 6和iOS 18环境中,调用BGTaskScheduler.shared.getPendingTaskRequests时应用崩溃,触发崩溃的核心调用为:

BGTaskScheduler.shared.getPendingTaskRequests

可能原因及解决方案

1. 避免在App初始化阶段调用异步后台任务API

App的init方法是同步执行的,此时App生命周期尚未完全就绪,iOS 18对后台任务的调用时机限制更严格,异步回调可能导致线程或状态异常。

修改方案:
移除init中的scheduleAppRefresh()调用,将任务调度逻辑移到App激活阶段(通过监听ScenePhase):

@main
struct YourApp: App {
    let backgroundAppRefreshTask = "com.example.app.refreshTask"
    @Environment(\.scenePhase) private var scenePhase

    init() {
        registerBackgroundTasks()
        // 移除这里的scheduleAppRefresh()
    }

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .onChange(of: scenePhase) { _, newPhase in
            if newPhase == .active {
                scheduleAppRefresh()
            }
        }
    }

    // 其余方法保持不变...
}

2. 确保后台任务权限配置完整

iOS 18要求必须在Info.plist中声明允许的后台任务标识符,否则调用BGTaskScheduler相关API可能崩溃。

添加配置:
在Info.plist中添加以下键值对:

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.example.app.refreshTask</string>
</array>
<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>
</array>

3. 修复不安全的强制类型转换

原代码中使用as! BGAppRefreshTask进行强制类型转换,若iOS 18对任务类型的返回逻辑有变更,会直接触发崩溃。

修改方案:
改用可选绑定安全转换:

func registerBackgroundTasks() {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: backgroundAppRefreshTask, using: nil) { task in
        guard let refreshTask = task as? BGAppRefreshTask else {
            task.setTaskCompleted(success: false)
            return
        }
        handleAppRefresh(task: refreshTask)
    }
}

4. 确保在主队列调用BGTaskScheduler API

iOS 18可能要求BGTaskScheduler的相关调用必须在主队列执行,异步回调的线程问题也可能导致崩溃。

修改方案:
将getPendingTaskRequests的调用包裹在主队列中:

func scheduleAppRefresh() {
    DispatchQueue.main.async {
        BGTaskScheduler.shared.getPendingTaskRequests { [weak self] taskRequests in
            guard let self = self else { return }
            
            if taskRequests.contains(where: { $0.identifier == self.backgroundAppRefreshTask }) {
                print("⚠️ Task Pending: '\(self.backgroundAppRefreshTask)' is already pending.")
                return
            }

            let request = BGAppRefreshTaskRequest(identifier: self.backgroundAppRefreshTask)
            if let nextHour = Calendar.current.nextDate(after: Date(), matching: DateComponents(minute: 0), matchingPolicy: .nextTime) {
                request.earliestBeginDate = nextHour
            }

            do {
                try BGTaskScheduler.shared.submit(request)
                print("✅ App refresh task '\(self.backgroundAppRefreshTask)' successfully scheduled.")
            } catch {
                print("❌ Failed to schedule app refresh task.")
            }
        }
    }
}

崩溃截图

崩溃截图

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 18:23:17