mcpField
B
background-execution

background-execution

github.com/n0an开发13250 次安装7 周前更新
代码仓库

关于 background-execution

面向 Swift 开发者的技能指南,帮助编写和审查应用进入后台或挂起后的任务代码。它按任务类型选择系统 API,并强调生命周期限制、完成处理和测试。

主要功能

  1. 01按任务目标选择后台 API
  2. 02检查 BGTaskScheduler 注册与完成
  3. 03审查后台 URLSession 与重启流程
  4. 04检查推送、定位和音频配置
  5. 05涵盖 SwiftUI 与 macOS 后台任务
  6. 06提供测试和常见问题指引

适用场景

  1. 01为内容刷新选择 BGAppRefreshTask
  2. 02让后台上传或下载正确完成
  3. 03排查后台任务未运行的原因

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/n0an/background-execution-agent-skill --skill background-execution

安装后在 Claude Code 中输入/background-execution确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

agents/
openai.yaml
references/
anti-patterns.md
background-audio.md
background-modes.md
background-push.md
background-url-session.md
bg-task-scheduler.md
fundamentals.md
macos-background.md
swiftui-background-tasks.md
task-assertions.md
testing-and-debugging.md

详细介绍

编写和审查 Swift 代码,使其在应用进入后台或暂停时仍能执行工作;为任务选择合适的 API,并遵守系统约束,确保工作确实运行且应用不会被终止。

审查流程:

  1. 使用 references/fundamentals.md 确认后台执行模型(生命周期、运行时限、强制退出和五项原则)。
  2. 使用下方的决策树确认所选 API 与任务相匹配;如果不匹配,则改用其他方案。
  3. 使用 references/bg-task-scheduler.md 验证 BGTaskScheduler 的用法(注册时机、Info.plist、过期处理、setTaskCompleted)。
  4. 使用 references/task-assertions.md 验证任务断言(beginBackgroundTask/endBackgroundTask、performExpiringActivity)。
  5. 使用 references/background-url-session.md 验证后台 URLSession 配置和重新启动流程。
  6. 使用 references/background-push.md 验证静默推送和 VoIP 推送的负载、标头及处理程序。
  7. 使用 references/background-modes.md 验证 UIBackgroundModes 声明和定位相关细节。
  8. 使用 references/background-audio.md 验证后台音频(会话类别、锁屏时录音、中断、路由更改、麦克风权限)。
  9. 使用 references/swiftui-background-tasks.md 验证 SwiftUI ScenePhase / .backgroundTask 的用法。
  10. 使用 references/macos-background.md 验证 macOS 调度器(NSBackgroundActivityScheduler、beginActivity、SMAppService)。
  11. 使用 references/testing-and-debugging.md 检查测试、调试和约束处理。
  12. 使用 references/anti-patterns.md 找出常见错误。

如果只处理部分内容,只加载相关的参考文件。

按任务选择参考文件

根据用户目标确定阅读顺序。只加载所需内容。

“在后台刷新我的应用内容”
  1. references/bg-task-scheduler.md - BGAppRefreshTask、注册、提交和过期处理
  2. references/testing-and-debugging.md - 模拟启动、处理 backgroundRefreshStatus
“在后台运行耗时维护 / ML / 清理任务”
  1. references/bg-task-scheduler.md - BGProcessingTask、电源和网络要求
  2. references/testing-and-debugging.md - 模拟启动和过期处理
“用户离开后,让其发起的导出继续运行(iOS 26)”
  1. references/bg-task-scheduler.md - BGContinuedProcessingTask、进度、提交策略、GPU
  2. references/fundamentals.md - 用户同意 / 用户发起原则
“应用进入后台后,完成正在进行的上传 / 保存”
  1. references/task-assertions.md - beginBackgroundTask/endBackgroundTask、performExpiringActivity
“下载或上传在暂停后仍能继续的大型文件”
  1. references/background-url-session.md - 后台配置、代理、重新启动流程
  2. references/testing-and-debugging.md - 强制退出和约束注意事项
“从服务器唤醒我的应用”
  1. references/background-push.md - 静默推送的负载 / 标头 / 处理程序,或用于通话的 PushKit
  2. references/background-modes.md - remote-notification 模式
“在后台持续播放音频”
  1. references/background-audio.md - audio 模式 + 活动会话、类别 / 模式 / 选项、中断、路由更改
“锁屏时录音 / 口述 / 转录”
  1. references/background-audio.md - .playAndRecord、锁屏时录音、麦克风权限、AVAudioEngine tap、生产环境注意事项
“在后台跟踪位置”
  1. references/background-modes.md - location 模式、显著位置变化和区域监控
“用 SwiftUI 的方式实现”
  1. references/swiftui-background-tasks.md - ScenePhase、.backgroundTask(.appRefresh/.urlSession)
  2. references/bg-task-scheduler.md - 仍需使用 BGTaskScheduler 安排任务
“macOS 上的后台工作”
  1. references/macos-background.md - NSBackgroundActivityScheduler、beginActivity、SMAppService
“我的后台任务从未运行/如何测试它”
  1. references/testing-and-debugging.md — lldb 模拟命令、控制执行的状态
  2. references/anti-patterns.md — 常见原因
“我遇到了错误或 App Review 问题”
  1. references/anti-patterns.md — 通过修复前后的示例说明问题

决策树

应该使用哪种后台 API?
Does the work require user consent or input mid-flight?
  -> Background runtime is wrong. Bring it to the foreground.

Is work already running and you just need to finish it as the app backgrounds?
  -> beginBackgroundTask / endBackgroundTask (apps)
  -> ProcessInfo.performExpiringActivity (app extensions, watchOS)

Is it a user-initiated long task that should continue with visible progress? (iOS/iPadOS 26)
  -> BGContinuedProcessingTask

Is it a large/long file download or upload that must survive suspension/termination?
  -> background URLSession

Does the server need to tell the app new content exists?
  -> background (silent) push  (apns-push-type: background, content-available: 1)

Is it an incoming call invitation?
  -> PushKit + CallKit (report the call on every push)

Is it periodic content refresh before the user opens the app?
  -> BGAppRefreshTask

Is it long, deferrable maintenance / ML / cleanup?
  -> BGProcessingTask (optionally requiresExternalPower / requiresNetworkConnectivity)

Does the app need to keep playing audio or recording the mic (incl. while locked)?
  -> audio UIBackgroundMode + active AVAudioSession (.playback or .playAndRecord)  [background-audio.md]

Does the app need to keep running for location / BLE / VoIP?
  -> declare the matching UIBackgroundModes capability  [background-modes.md]

macOS, deferrable repeating maintenance?
  -> NSBackgroundActivityScheduler

macOS, keep critical non-UI work from being napped?
  -> ProcessInfo.beginActivity / performActivity
应该使用哪种 BGTask 类型?
Short content refresh, system picks the time around app usage?
  -> BGAppRefreshTask          (UIBackgroundModes: fetch)

Long maintenance, ideally on charger + network?
  -> BGProcessingTask          (UIBackgroundModes: processing; requiresExternalPower / requiresNetworkConnectivity)

User-tapped long work with progress UI, continues after backgrounding? (iOS 26)
  -> BGContinuedProcessingTask (title/subtitle, progress, submission strategy, optional .gpu)

Long processing of health-research-study data? (iOS 17)
  -> BGHealthResearchTask

核心指令

  • 绝不要将后台执行视为必然。它是机会性且由系统酌情安排的;设计每项功能时都要提供前台对账路径,绝不要将正确性关键逻辑仅放在后台任务中。
  • 绝不要在惰性时、视图代码中或启动完成后注册 BGTaskScheduler 处理程序。必须在 App.init() / application(_:didFinishLaunchingWithOptions:) 中注册所有处理程序,因为系统可能会直接在后台启动应用。(BGContinuedProcessingTask 是唯一例外——它会根据用户意图动态注册。)
  • 绝不要重复注册同一个任务标识符——这会导致应用崩溃。
  • 绝不要省略 BGTask 的过期处理程序;没有该处理程序时,系统会静默地将任务标记为已完成但未成功。设置该处理程序,让它快速取消工作,并且只调用一次 setTaskCompleted(success:)。
  • 绝不要忘记重新安排任务。BGTaskScheduler 请求是一次性的;应将提交下一项请求作为启动处理程序的第一行代码。
  • 仅在 BGProcessingTaskRequest 上设置 requiresExternalPower / requiresNetworkConnectivity,绝不要在应用刷新请求上设置。将 earliestBeginDate 视为最早开始时间,而不是执行计划。
  • 绝不要让 beginBackgroundTask 调用失去配对。在成功路径和过期处理程序中都要调用 endBackgroundTask,并确保调用幂等(通过 .invalid 检查);未配对会触发断言并杀死应用。必须在开始工作前调用 beginBackgroundTask,而不是等到后台状态转换委托方法末尾才调用。
  • 绝不要将 backgroundTimeRemaining 当作真实的时间预算——它在前台是 DBL_MAX,在后台也只是参考值。按约 30 秒规划,并依赖过期处理程序。
  • 仅使用 beginBackgroundTask(应用)或 performExpiringActivity(扩展、watchOS)来完成正在运行的工作,绝不要用它们来启动新的长时间工作或安排未来的工作。
  • 绝不要在后台 URLSession 上使用带完成处理程序的便捷方法或 dataTask;后台会话必须使用委托。每个标识符只创建一个会话,存储该会话,并在应用重新启动时使用完全相同的标识符和配置重新创建。
  • 实现完整的后台 URLSession 重新启动流程:存储 handleEventsForBackgroundURLSession 传入的处理程序,重新创建会话,并在 urlSessionDidFinishEvents(forBackgroundURLSession:) 中于主线程调用已存储的处理程序。在回调中同步移动 didFinishDownloadingTo 的 location 指向的文件。
  • 对于后台上传,使用基于文件的 uploadTask(with:fromFile:)——应用退出后,数据和流上传会失败。
  • 绝不要发送缺少 apns-push-type: background(以及 apns-priority: 5)的静默推送,并且 aps 字典中只能包含 content-available。必须在约 30 秒内调用抓取完成处理程序。静默推送可能会被节流和合并,不可靠。
  • 在 iOS 13 及更高版本中,每次收到 VoIP 推送时都必须向 CallKit 报告来电,否则系统会终止应用并撤销 VoIP 推送权限。绝不要将 VoIP 推送用于非通话数据。
  • 绝不要在未启用 location 后台模式的情况下设置 allowsBackgroundLocationUpdates = true——这会导致致命错误。优先使用重大变化监测/区域监测,而不是持续运行的 location 模式。
  • 后台音频需要同时启用 audio 模式,并激活具有后台运行能力类别的 AVAudioSession(播放使用 .playback,锁屏录音使用 .playAndRecord / .record);仅启用该模式没有作用。在音频开始时(而非启动时)激活会话,并使用 .notifyOthersOnDeactivation 停用会话。始终处理 interruptionNotification(恢复前检查 .shouldResume)和 routeChangeNotification(在 .oldDeviceUnavailable 时暂停)。
  • 麦克风采集需要通过 AVAudioApplication.requestRecordPermission()(iOS 17+)请求权限,并声明 NSMicrophoneUsageDescription——缺少该键会导致应用崩溃;未获权限时,采集会返回静音的零值样本,而不是错误。必须在主执行器之外安装 AVAudioEngine tap(闭包会在实时线程上运行),并让 AVAudioFile 设置与输入节点的格式匹配。
  • 谨慎声明 UIBackgroundModes;App Review 会拒绝缺乏正当理由的模式。优先采用更轻量的替代方案。
  • 考虑用户行为:用户强制退出后,BGTaskScheduler、静默推送和后台 URLSession 重新启动都会被抑制,直到下次手动启动应用。读取 backgroundRefreshStatus(在 .denied 时降低功能,在 .restricted 时保持静默),并在低电量模式和热状态升高时退避。
  • 与后台相关的设置(任务注册、会话重新创建、依赖项连接)应放在每次启动都会运行的路径中,而不是 .onAppear / .task 中——后台启动可能根本不会构建 UI。
  • 启用场景后,使用 sceneDidEnterBackground(_:)(而不是已弃用的 applicationDidEnterBackground(_:));该方法必须在约 5 秒内返回。
  • 在 macOS 上,对可延后维护使用 NSBackgroundActivityScheduler,并使用 ProcessInfo.beginActivity / endActivity(成对调用,或使用 performActivity)来控制 App Nap;macOS 上不存在 performExpiringActivity。
  • 在真机上使用 lldb 的 _simulateLaunchForTaskWithIdentifier: / _simulateExpirationForTaskWithIdentifier: 命令测试后台任务——绝不要发布对这些命令的引用。始终测试过期路径。

输出格式

如果用户要求审查,请按文件整理问题。每个问题:

  1. 写明文件和相关行号。
  2. 指出要替换的反模式。
  3. 展示简短的修改前/修改后代码。

跳过没有问题的文件。最后按优先级总结最值得优先处理的改动。

如果用户要求编写或修复后台执行代码,请直接进行修改,而不是返回问题报告。

示例输出:

SyncManager.swift

第 22 行:在 .onAppear 中注册 BGTaskScheduler 处理程序——后台启动时永远不会运行。

// Before
.onAppear {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: id, using: nil) { ... }
}

// After - register in App.init() / didFinishLaunching
init() {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: id, using: nil) { task in
        self.handleRefresh(task: task as! BGAppRefreshTask)
    }
}

第 48 行:缺少过期处理程序和 setTaskCompleted——应用会在任务过期时被终止。

// Before
func handleRefresh(task: BGAppRefreshTask) { refresh() }

// After
func handleRefresh(task: BGAppRefreshTask) {
    scheduleNext()
    let op = RefreshOperation()
    task.expirationHandler = { op.cancel() }
    op.completionBlock = { task.setTaskCompleted(success: !op.isCancelled) }
    queue.addOperation(op)
}
总结
  1. **注册时机(高):**将处理程序移至 App.init(),否则后台启动时永远不会触发。
  2. **完成约定(高):**添加过期处理程序,并确保只调用一次 setTaskCompleted。

示例结束。

参考资料

  • references/fundamentals.md - 执行模型:前台/后台/挂起、系统预算、强制退出、用户开关、五项原则、生命周期和场景状态、“该用哪个 API”对照表。
  • references/bg-task-scheduler.md - BackgroundTasks:BGAppRefreshTask、BGProcessingTask、BGContinuedProcessingTask(iOS 26)、BGHealthResearchTask、注册、Info.plist 键、提交、过期、错误。
  • references/task-assertions.md - beginBackgroundTask/endBackgroundTask、backgroundTimeRemaining、ProcessInfo.performExpiringActivity、断言与 BGTaskScheduler。
  • references/background-url-session.md - 后台 URLSession 配置、必需的代理、重新启动 / handleEventsForBackgroundURLSession 流程、可调参数、恢复数据。
  • references/background-push.md - 静默/后台推送(负载、标头、处理程序、节流)、PushKit/VoIP 及 CallKit 要求。
  • references/background-modes.md - UIBackgroundModes 矩阵、后台定位、BLE/配件/PTT、已弃用的后台抓取。
  • references/background-audio.md - 后台播放和录制:AVAudioSession 类别/模式/选项、锁屏时录制、麦克风权限、中断、路由更改、AVAudioEngine tap 和生产环境注意事项。
  • references/swiftui-background-tasks.md - ScenePhase、.backgroundTask 场景修饰符、异步取消、调度与处理。
  • references/macos-background.md - NSBackgroundActivityScheduler、ProcessInfo.beginActivity/App Nap、SMAppService、跨平台对照表。
  • references/testing-and-debugging.md - lldb 模拟启动/过期、backgroundRefreshStatus、低电量模式、热状态、执行的门控条件。
  • references/anti-patterns.md - LLM 生成后台执行代码时常见的错误。

评论

支持 Markdown