Finish tasks in the background
2025年6月9日
一句话判断
BGContinuedProcessingTask 是 iOS 26 最值得关注的后台 API — 用户点了”导出视频”然后切到后台,系统接管任务并显示进度 UI,用户随时可以取消。这解决了”用户发起的长任务切后台就挂掉”的老问题。
这场 Session 讲了什么
Ryan 系统讲解了 iOS 后台运行的完整图景:
后台运行的基本约束:app 进入后台后默认被 suspend,不分配 CPU 时间。系统的核心目标是保护电池、优化性能、维护前台体验。后台任务的原则:Efficient(高效)、Minimal(最小化)、Resilient(弹性,保存增量进度)、Courteous(礼貌,尊重用户设置)、Adaptive(自适应系统条件)。
现有 API 回顾:
BGAppRefreshTask:基于 app 使用频率调度的静默内容获取,适合在用户打开 app 前预加载新内容。- Background Push Notifications:服务器推送通知触发后台内容更新,始终是 discretionary 的。
BGProcessingTask:执行 ML 推理、数据库维护等非获取型任务,支持配置”仅在充电时运行”。beginBackgroundTask/endBackgroundTask:app 转后台时的额外运行时间,适合清理文件句柄等短任务。
新 API — BGContinuedProcessingTask:iOS 26 新增。专门处理用户发起的长任务(如视频导出、社交媒体发布、配件更新)。特点:
- 必须由用户显式操作触发(按钮点击、手势等),不能自动启动。
- 系统提供进度 UI 显示标题、副标题和进度条。
- 用户可以随时取消任务。
- 支持通配符标识符(
bundleID.context.*)。 - 支持 background GPU 访问(需在 Xcode 中添加 capability)。
- 提交策略:默认排队,也可指定”必须立即启动否则失败”。
值得深挖的点
-
BGContinuedProcessingTask的核心原则是 consent。任务必须由用户明确发起,系统显示进度 UI 让用户保持知情和控制权。如果你的任务是自动启动的(备份、照片同步等),请用其他 API。 -
进度报告是强制要求。不报告进度的任务会被系统 expire。使用
Progressreporting protocol 持续更新进度,系统会将其显示在 UI 中。如果进度太慢,系统会提示用户是否继续。 -
通配符标识符允许你动态注册任务。格式是
bundleID.semanticContext.*,适合需要为不同操作类型创建多个任务的场景(如不同文件的导出任务)。 -
后台任务的优先级在 app 回到前台时会提升。系统会智能提升你 app 相关任务的优先级,保持响应性。
代码片段
注册和提交 BGContinuedProcessingTask:
// 1. 在 Info.plist 中添加标识符
// BGTaskSchedulerPermittedIdentifiers: ["com.myapp.export.*"]
// 2. 动态注册 launch handler(不需要在 launch 时注册)
BGTaskScheduler.shared.register(
forTaskWithIdentifier: "com.myapp.export.video",
using: nil
) { task in
guard let task = task as? BGContinuedProcessingTask else { return }
task.expirationHandler = {
shouldCancel = true
}
let progress = Progress(totalUnitCount: 100)
task.progress = progress
await exportVideo(progress: progress)
task.setTaskCompleted(success: true)
}
// 3. 用户点击导出按钮时提交
let request = BGContinuedProcessingTaskRequest(
identifier: "com.myapp.export.video",
title: "Exporting Video",
subtitle: "Your video is being exported in the background"
)
request.queuesIfCannotStartImmediately = true
try BGTaskScheduler.shared.submit(request)
最佳实践
-
为每个后台任务选择正确的 API。用户发起的长任务 ->
BGContinuedProcessingTask。静默预取 ->BGAppRefreshTask。服务器推送更新 -> Background Push。离线批处理 ->BGProcessingTask。短时间收尾 ->beginBackgroundTask。 -
任务必须报告进度。使用
Progress对象并持续更新completedUnitCount,否则系统会认为任务卡死并 expire 它。 -
处理 expiration 优雅退出。在
expirationHandler中设置取消标志,让任务循环检查并尽快退出。调用setTaskCompleted告诉系统你已完成。 -
不要用
BGContinuedProcessingTask做自动任务。如果任务不是由用户显式操作触发的,用户可能不理解进度 UI 的含义并取消它。这种场景用BGProcessingTask或BGAppRefreshTask。 -
检查 supportedResources。如果你的任务需要 GPU,先查询
scheduler.supportedResources确认设备支持,再设置 requirements。
还有什么值得关注
- CarPlay 现在支持 Live Activities,可以在车载屏幕上显示实时更新(如导航进度、外卖状态)。
- Background Tasks API 的更新与 visionOS 26 的 enterprise 功能也有交叉 — 后台任务在空间计算场景中同样重要。
- 如果你在做视频编辑、音频处理等 GPU 密集型任务,新的 background GPU 支持是重大利好。