Finish tasks in the background
System Services 进阶 1m

Finish tasks in the background

2025年6月9日

在 Apple 官方观看视频

一句话判断

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)。
  • 提交策略:默认排队,也可指定”必须立即启动否则失败”。

值得深挖的点

  1. BGContinuedProcessingTask 的核心原则是 consent。任务必须由用户明确发起,系统显示进度 UI 让用户保持知情和控制权。如果你的任务是自动启动的(备份、照片同步等),请用其他 API。

  2. 进度报告是强制要求。不报告进度的任务会被系统 expire。使用 Progress reporting protocol 持续更新进度,系统会将其显示在 UI 中。如果进度太慢,系统会提示用户是否继续。

  3. 通配符标识符允许你动态注册任务。格式是 bundleID.semanticContext.*,适合需要为不同操作类型创建多个任务的场景(如不同文件的导出任务)。

  4. 后台任务的优先级在 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)

最佳实践

  1. 为每个后台任务选择正确的 API。用户发起的长任务 -> BGContinuedProcessingTask。静默预取 -> BGAppRefreshTask。服务器推送更新 -> Background Push。离线批处理 -> BGProcessingTask。短时间收尾 -> beginBackgroundTask

  2. 任务必须报告进度。使用 Progress 对象并持续更新 completedUnitCount,否则系统会认为任务卡死并 expire 它。

  3. 处理 expiration 优雅退出。在 expirationHandler 中设置取消标志,让任务循环检查并尽快退出。调用 setTaskCompleted 告诉系统你已完成。

  4. 不要用 BGContinuedProcessingTask 做自动任务。如果任务不是由用户显式操作触发的,用户可能不理解进度 UI 的含义并取消它。这种场景用 BGProcessingTaskBGAppRefreshTask

  5. 检查 supportedResources。如果你的任务需要 GPU,先查询 scheduler.supportedResources 确认设备支持,再设置 requirements。

还有什么值得关注

  • CarPlay 现在支持 Live Activities,可以在车载屏幕上显示实时更新(如导航进度、外卖状态)。
  • Background Tasks API 的更新与 visionOS 26 的 enterprise 功能也有交叉 — 后台任务在空间计算场景中同样重要。
  • 如果你在做视频编辑、音频处理等 GPU 密集型任务,新的 background GPU 支持是重大利好。
系统服务