BGTaskScheduler — 是 Apple 的框架,用于在 iOS 13 及更高版本的应用程序中计划和执行后台任务。它取代了过时的 Background Fetch 和 performFetch,为后台操作提供了统一的 API。根据 Apple Developer Documentation, 2026,该框架包括两种类型的任务:用于长时间操作的 BGProcessingTask 和用于短内容更新的 BGAppRefreshTask。
要点
BGTaskScheduler — 是 Apple 的系统框架,在 iOS 13 中引入,集中管理后台任务的执行。在其出现之前,开发人员使用 UIApplication backgroundTasks、performFetch 和 appDelegate 中的事件处理,这导致了代码碎片化和不可预测的行为。
该框架基于延迟计划原则工作:应用程序使用唯一标识符注册任务,iOS 自行确定执行它们的最佳时机。系统考虑电池电量、用户活动、网络状态等因素。
主要功能 包括处理短时间和长时间的后台操作。与 Android 中的 AlarmManager 不同,BGTaskScheduler 不保证精确的执行时间——系统保留在条件不利时推迟任务的权利。
BGTaskScheduler 使用基于处理程序的架构。应用程序为每种任务类型注册一个处理程序,系统在适当时刻调用它。该框架本身不直接执行任务——它仅通知应用程序是时候启动它了。
注册从在 Info.plist 中通过 BGTaskSchedulerPermittedIdentifiers 数组声明任务标识符开始。然后在应用程序代码中调用 registerHandler(forTaskWithIdentifier:) 方法与处理程序闭包。
import BackgroundTasks
let taskID = "com.example.app.refresh"
BGTaskScheduler.shared.registerHandler(
forTaskWithIdentifier: taskID,
using: DispatchQueue.global()
) { task in
task.expirationHandler = {
// 在强制终止时调用
}
processBackgroundTask(task as! BGAppRefreshTask)
}
注册后,应用程序必须通过 submitTaskRequest 明确请求任务执行。请求包含任务标识符和最早可能开始的日期。系统保存请求并在认为条件合适时处理它。
let request = BGAppRefreshTaskRequest(
identifier: taskID
)
request.earliestBeginDate = Date(timeIntervalSinceNow: 3600)
do {
try BGTaskScheduler.shared.submit(request)
} catch {
print("计划错误:\(error)")
}
BGTaskScheduler 提供两种主要任务类型,每种都针对自己的使用场景设计。选择合适的类型直接影响系统成功执行任务的可能性。
BGAppRefreshTask 设计用于短的后台内容更新:加载新数据、与服务器同步、更新小部件。执行时间限制为 30 秒,之后系统强制终止任务。这种任务类型比 BGProcessingTask 更频繁地执行,并具有更高的优先级。
BGProcessingTask 设计用于更长的操作:处理媒体文件、索引 Core Data 数据、创建备份。任务可以持续数分钟,但系统不太频繁地启动它,并且仅在有利条件下——连接到电源、稳定的 Wi-Fi 和低设备负载时。
| 参数 | BGAppRefreshTask | BGProcessingTask |
|---|---|---|
| 时间限制 | 30 秒 | 数分钟 |
| 启动频率 | 高 | 低 |
| 条件 | 任意 | 电源 + Wi-Fi |
| 需要电源 | 否 | 建议 |
| 示例 | 更新信息流 | 处理视频 |
正确注册 — 是 BGTaskScheduler 工作的必要条件。如果任务未在 Info.plist 中注册,系统将忽略任何执行任务的请求。
在 Info.plist 文件中添加一个 BGTaskSchedulerPermittedIdentifiers 数组,其中包含文本标识符列表。每个标识符在应用程序范围内必须是唯一的。Apple 建议使用反向域表示法。
<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
<string>com.example.app.refresh</string>
<string>com.example.app.processing</string>
</array>
计划使用 submitTaskRequest 方法。如果不再需要任务,可以通过 cancelTaskRequest 或 cancelAllTaskRequests 取消它。系统在删除应用程序或重置数据时自动取消任务。
BGTaskScheduler 提供通过 getPendingTaskRequests 跟踪已计划任务状态的能力。此方法返回所有活动请求的列表,包括它们的类型、标识符和 earliestBeginDate 信息。对于每个请求,可以检查它是否已执行或取消,并决定重新计划。
重要的是,系统不提供关于后台任务执行成功的直接回调——处理程序本身必须通过任务属性报告结果。setTaskCompleted 允许将任务标记为成功完成,之后系统可以启动此类型的下一个已计划任务。如果任务未调用 setTaskCompleted,系统将在时间到期或强制终止时认为它已完成。
对于问题诊断,建议在处理程序中使用 OSLog,并通过 Mac 上的 Console.app 查看日志。Apple 还提供 MetricKit 工具用于分析后台任务性能——它收集有关执行时间、能量消耗和启动频率的数据,可用于优化。
// 取消特定任务
BGTaskScheduler.shared.cancel(taskRequestWithIdentifier: taskID)
// 取消所有任务
BGTaskScheduler.shared.cancelAllTaskRequests()
// 检查已计划的任务
BGTaskScheduler.shared.getPendingTaskRequests { requests in
print("已计划 \(requests.count) 个任务")
}
BGTaskScheduler 对后台工作施加严格限制。如果条件不利,系统可以将任务无限期推迟。开发人员必须理解该框架不适用于实时任务。
关键限制包括:系统不保证在指定时间执行任务,同时任务的最大数量有限,能量消耗 受到严格控制。连续启动多个任务可能导致它们合并或取消。
为提高执行可能性,建议将 earliestBeginDate 设置为不早于 BGProcessingTask 的 1 小时 和 BGAppRefreshTask 的 15 分钟。处理 expirationHandler 也很重要——如果任务超出限制,系统调用此处理程序以正确终止。重新计划应在处理程序内部进行,以保持后台工作的连续循环。
另一个重要限制涉及 网络请求。BGTaskScheduler 不保证在执行任务期间存在活动的网络连接。应用程序必须通过 NWPathMonitor 自行检查网络可用性,如果没有连接则推迟处理。这不同于 Android JobScheduler,后者仅在连接到特定类型的网络时才能激活任务。在实践中,开发人员经常将 BGTaskScheduler 与 NSURLSession 的后台 URL 会话结合使用,以实现可靠的数据加载。
从 macOS Catalina 开始,BGTaskScheduler 也可在 Mac 上使用。这允许为在 Apple Silicon 上运行的 UIKit 应用程序创建跨平台后台任务。在 watchOS 上,框架功能有限——仅提供短 BGAppRefreshTask 用于更新复杂功能块和与 iPhone 同步数据。开发人员在计划后台架构时必须考虑平台差异。
Apple 提供了多种工具用于调试 BGTaskScheduler。lldb 中的命令 e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] 强制启动后台任务,忽略系统限制。Xcode 的 Debug 菜单中提供了 Simulate Background Fetch 标志,用于模拟短后台更新。性能分析使用 MetricKit——它收集有关每个任务的启动频率、执行持续时间和能量消耗的信息。这些数据有助于优化计划频率和选择正确的任务类型。
在实践中,BGTaskScheduler 适用于更新小部件数据、iCloud 同步、处理带有内容推送通知和 Spotlight 搜索索引。不适用于发送实时分析、聊天应用程序或任何需要立即执行的任务。
为了深入学习 BGTaskScheduler,Apple 推荐官方 WWDC 文档:“Advances in Background Tasks”(2020)会议涵盖从过时 API 的迁移,“Background Tasks in Practice”(2021)包含实际用例。Energy Efficiency Guide 部分也很有用,其中描述了该框架如何融入 Apple 的整体节能策略。代码示例可在 GitHub 的 Apple Developer 官方仓库中找到,包含 iOS 和 macOS 的完整项目。
常见问题
Background Fetch 限制为每个应用程序一个后台任务,并且没有优先级机制。BGTaskScheduler 支持多种不同类型的任务,提供统一的 API 和自动能量管理。
Apple 没有对注册标识符的数量设定明确限制,但在实践中建议使用不超过 5–10 个任务。数量更多会因系统资源竞争而降低每个特定任务执行的可能性。
使用 lldb 中的命令 e -l objc -- (void)[[BGTaskScheduler sharedScheduler] _simulateLaunchForTaskWithIdentifier:@"com.example.task"] 进行调试。它强制启动任务,绕过系统限制。Xcode 的 Debug 菜单中也提供了 Simulate Background Fetch 标志。
是的,BGTaskScheduler 可以在应用程序被用户强制关闭时启动进程。但是,系统可能会应用额外的延迟,并且并非所有任务类型都能保证在此场景中启动。
系统将调用 expirationHandler,向任务发送需要终止的信号。如果应用程序忽略此信号并继续工作,iOS 将强制终止进程。之后,系统可能降低应用程序所有后台任务的优先级。
总结
我们将开发一款交钥匙移动应用程序
IT Sectr自2017年以来为初创企业和企业打造iOS和Android应用程序。我们将为您提供咨询并提出最佳解决方案。