0Pricing
Swift Academy · 课时

后台任务与刷新

使用 BGTaskScheduler 调度后台工作。

后台任务与刷新 是 CoddyKit 上的免费 Swift Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Swift Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Swift Academy 课程共包含 4 节课。

后台任务为何存在

iOS 会积极挂起应用以节省电量。若要在应用处于后台时执行有意义的工作(例如刷新信息流或处理下载),请通过 BGTaskScheduler 安排任务。系统会在需求、耗电量和使用模式之间进行平衡,自行决定何时运行任务。

import BackgroundTasks
// You request work; the system schedules it later
// at an opportune moment (charging, on Wi-Fi, etc.)

两种任务类型

任务有两种:BGAppRefreshTask 用于短暂且频繁的更新(几秒钟),BGProcessingTask 用于较长时间、较繁重的工作(几分钟),例如数据库维护,并且可以选择要求接入电源或网络。

import BackgroundTasks
// BGAppRefreshTask  -> quick content refresh
// BGProcessingTask  -> long maintenance, can require
//                      external power / network

声明标识符

每个任务都需要一个唯一标识符,并且必须在 Info.plist 的 BGTaskSchedulerPermittedIdentifiers 下列出。没有这项声明,注册就会失败。请使用反向 DNS 格式的字符串。

// Info.plist:
// BGTaskSchedulerPermittedIdentifiers = [
//   "com.example.app.refresh",
//   "com.example.app.cleanup"
// ]
let ids = "declare every identifier in Info.plist"
_ = ids

注册处理程序

在启动时,为每个标识符通过 BGTaskScheduler.shared.register 注册处理程序。此操作必须在应用完成启动之前进行。之后,系统每当决定执行任务时,就会运行相应的处理程序。

import BackgroundTasks
func registerTasks() {
    BGTaskScheduler.shared.register(
        forTaskWithIdentifier: "com.example.app.refresh",
        using: nil) { task in
        handleRefresh(task as! BGAppRefreshTask)
    }
}

提交请求

注册只会连接处理程序。若要真正请求运行任务,请创建 BGAppRefreshTaskRequest,设置最早开始日期,然后调用 submit。系统会将该日期视为提示,而不是保证。

import BackgroundTasks
func scheduleRefresh() {
    let request = BGAppRefreshTaskRequest(
        identifier: "com.example.app.refresh")
    request.earliestBeginDate = Date(
        timeIntervalSinceNow: 15 * 60)
    try? BGTaskScheduler.shared.submit(request)
}

始终重新安排

已提交的请求最多只会运行一次。若要持续刷新,处理程序必须在结束前提交下一次请求。请先重新安排,再执行工作,这样即使工作中途崩溃,也不会停止整个循环。

import BackgroundTasks
func handleRefresh(_ task: BGAppRefreshTask) {
    scheduleRefresh() // queue the next run first
    // ... then perform this run's work
}

报告完成

完成后必须调用 task.setTaskCompleted(success:)。忘记调用会浪费后台执行额度,还可能导致系统降低今后任务的优先级。请传入工作是否成功,以便系统调整后续安排。

import BackgroundTasks
func handleRefresh(_ task: BGAppRefreshTask) {
    scheduleRefresh()
    Task {
        let ok = await fetchLatest()
        task.setTaskCompleted(success: ok)
    }
}
func fetchLatest() async -> Bool { true }

遵守过期处理程序

系统可能会提前收回执行时间。请设置 task.expirationHandler,取消正在进行的工作并完成清理,以便在时间被缩短时正常退出。请将它视为截止时间警报。

import BackgroundTasks
func handle(_ task: BGAppRefreshTask) {
    let work = Task { await fetchLatest() }
    task.expirationHandler = {
        work.cancel() // stop before the OS suspends us
    }
}
func fetchLatest() async -> Bool { true }

带要求的处理任务

对于繁重的工作,BGProcessingTaskRequest 允许您设置 requiresNetworkConnectivity 和 requiresExternalPower。系统会等待这些条件满足,因此长时间任务可以在设备夜间充电并连接无线网络时运行。

import BackgroundTasks
func scheduleCleanup() {
    let req = BGProcessingTaskRequest(
        identifier: "com.example.app.cleanup")
    req.requiresExternalPower = true
    req.requiresNetworkConnectivity = false
    try? BGTaskScheduler.shared.submit(req)
}

在调试器中测试

您不必等待数小时让系统安排任务。请在调试器中暂停,并运行 LLDB 命令强制已注册的任务立即启动,从而端到端验证处理程序。

// In LLDB while paused:
// e -l objc -- (void)[[BGTaskScheduler sharedScheduler]
//   _simulateLaunchForTaskWithIdentifier:
//   @"com.example.app.refresh"]
let test = "force-launch task via LLDB"
_ = test

完整的刷新循环

将整个流程串联起来:在启动时注册,在进入后台时提交请求;在处理程序中重新安排任务、通过过期处理程序进行保护、执行异步工作,并报告完成状态。

import BackgroundTasks
func handleRefresh(_ task: BGAppRefreshTask) {
    scheduleRefresh()
    let work = Task { await fetchLatest() }
    task.expirationHandler = { work.cancel() }
    Task {
        let ok = await work.value
        task.setTaskCompleted(success: ok)
    }
}
func fetchLatest() async -> Bool { true }

快速检查

请回顾重复刷新任务的生命周期。

回顾

您已学会后台调度:

  • 使用 BGAppRefreshTask 进行短暂刷新,使用 BGProcessingTask 进行需要电源或网络条件的长期维护。
  • 在 Info.plist 中声明标识符,在启动时通过 register 注册处理程序,并使用 earliestBeginDate 提交请求。
  • 在处理程序中重新安排下一次运行,设置 expirationHandler,并始终调用 setTaskCompleted。
  • 通过 LLDB 强制启动任务进行测试。

常见问题解答

「后台任务与刷新」课时是免费的吗?

是的 — 「后台任务与刷新」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Swift Academy 课程的其余内容,请升级到 CoddyKit PRO。 Swift Academy 课程共包含 4 节课。

「后台任务与刷新」这节课中我会学到什么?

使用 BGTaskScheduler 调度后台工作。 你通过在浏览器中直接运行的动手代码来练习 Swift Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Swift Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Swift Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「后台任务与刷新」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Swift Academy 课中编写并运行代码吗?

能。每节 Swift Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 注册推送通知
  2. 处理通知载荷
  3. 后台任务与刷新
  4. 通知操作与类别
← 返回 Swift Academy