background-execution

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese
Write and review Swift code that runs work while the app is backgrounded or suspended, choosing the right API for the job and respecting the system's constraints so the work actually runs and the app is not terminated.
Review process:
  1. Establish the background execution model (lifecycle, budgets, force-quit, the five principles) using
    references/fundamentals.md
    .
  2. Confirm the chosen API matches the work using the decision tree below; reroute if it does not.
  3. Validate
    BGTaskScheduler
    usage (registration timing, Info.plist, expiration,
    setTaskCompleted
    ) using
    references/bg-task-scheduler.md
    .
  4. Validate task assertions (
    beginBackgroundTask
    /
    endBackgroundTask
    ,
    performExpiringActivity
    ) using
    references/task-assertions.md
    .
  5. Validate background
    URLSession
    config and the relaunch flow using
    references/background-url-session.md
    .
  6. Validate silent/VoIP push payloads, headers, and handlers using
    references/background-push.md
    .
  7. Validate
    UIBackgroundModes
    declarations and location specifics using
    references/background-modes.md
    .
  8. Validate background audio (session category, recording while locked, interruptions, route changes, mic permission) using
    references/background-audio.md
    .
  9. Validate SwiftUI
    ScenePhase
    /
    .backgroundTask
    usage using
    references/swiftui-background-tasks.md
    .
  10. Validate macOS schedulers (
    NSBackgroundActivityScheduler
    ,
    beginActivity
    ,
    SMAppService
    ) using
    references/macos-background.md
    .
  11. Check testing/debugging and constraint handling using
    references/testing-and-debugging.md
    .
  12. Catch common mistakes using
    references/anti-patterns.md
    .
If doing partial work, load only the relevant reference files.
编写和审核可在应用进入后台或挂起状态时运行的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
    排查常见错误。
若仅处理部分任务,只需加载相关参考文件即可。

Task-based routing

基于任务的路由

Match the user's goal to the read order. Load only what you need.
根据用户目标匹配阅读顺序,仅加载所需内容。

"Refresh my app's content in the background"

"在后台刷新应用内容"

  1. references/bg-task-scheduler.md
    -
    BGAppRefreshTask
    , register/submit/expiration
  2. references/testing-and-debugging.md
    - simulate the launch, handle
    backgroundRefreshStatus
  1. references/bg-task-scheduler.md
    -
    BGAppRefreshTask
    ,注册/提交/过期处理
  2. references/testing-and-debugging.md
    - 模拟启动,处理
    backgroundRefreshStatus

"Run long maintenance / ML / cleanup in the background"

"在后台运行长时间维护/机器学习/清理任务"

  1. references/bg-task-scheduler.md
    -
    BGProcessingTask
    , power/network requirements
  2. references/testing-and-debugging.md
    - simulate launch and expiration
  1. references/bg-task-scheduler.md
    -
    BGProcessingTask
    ,电源/网络要求
  2. references/testing-and-debugging.md
    - 模拟启动和过期

"Let a user-started export keep running after they leave (iOS 26)"

"让用户发起的导出任务在离开后继续运行(iOS 26)"

  1. references/bg-task-scheduler.md
    -
    BGContinuedProcessingTask
    , progress, submission strategy, GPU
  2. references/fundamentals.md
    - the consent / user-initiated principle
  1. references/bg-task-scheduler.md
    -
    BGContinuedProcessingTask
    ,进度、提交策略、GPU使用
  2. references/fundamentals.md
    - 同意/用户发起原则

"Finish an in-flight upload / save when the app backgrounds"

"应用进入后台时完成正在进行的上传/保存操作"

  1. references/task-assertions.md
    -
    beginBackgroundTask
    /
    endBackgroundTask
    ,
    performExpiringActivity
  1. references/task-assertions.md
    -
    beginBackgroundTask
    /
    endBackgroundTask
    、
    performExpiringActivity

"Download or upload a large file that survives suspension"

"下载或上传大文件,且任务在应用挂起/终止后仍能继续"

  1. references/background-url-session.md
    - background config, delegate, the relaunch flow
  2. references/testing-and-debugging.md
    - force-quit and constraint caveats
  1. references/background-url-session.md
    - 后台配置、代理、重启流程
  2. references/testing-and-debugging.md
    - 强制退出和约束注意事项

"Wake my app from the server"

"通过服务器唤醒应用"

  1. references/background-push.md
    - silent push payload/headers/handler, or PushKit for calls
  2. references/background-modes.md
    - the
    remote-notification
    mode
  1. references/background-push.md
    - 静默推送负载/头信息/处理器,或用于通话的PushKit
  2. references/background-modes.md
    -
    remote-notification
    模式

"Keep playing audio in the background"

"在后台持续播放音频"

  1. references/background-audio.md
    - the
    audio
    mode + active session, category/mode/options, interruptions, route changes
  1. references/background-audio.md
    -
    audio
    模式 + 活跃会话,类别/模式/选项、中断处理、路由变更

"Record / dictate / transcribe with the screen locked"

"锁屏状态下录制/听写/转录"

  1. references/background-audio.md
    -
    .playAndRecord
    , recording while locked, mic permission, AVAudioEngine taps, the production gotchas
  1. references/background-audio.md
    -
    .playAndRecord
    、锁屏录制、麦克风权限、AVAudioEngine taps、生产环境注意事项

"Track location in the background"

"在后台追踪位置"

  1. references/background-modes.md
    - the
    location
    mode, significant-change and region monitoring
  1. references/background-modes.md
    -
    location
    模式,重大变更和区域监控

"Do this the SwiftUI way"

"用SwiftUI的方式实现"

  1. references/swiftui-background-tasks.md
    -
    ScenePhase
    ,
    .backgroundTask(.appRefresh/.urlSession)
  2. references/bg-task-scheduler.md
    - you still schedule with
    BGTaskScheduler
  1. references/swiftui-background-tasks.md
    -
    ScenePhase
    、
    .backgroundTask(.appRefresh/.urlSession)
  2. references/bg-task-scheduler.md
    - 仍需通过
    BGTaskScheduler
    调度任务

"Background work on macOS"

"macOS上的后台任务"

  1. references/macos-background.md
    -
    NSBackgroundActivityScheduler
    ,
    beginActivity
    ,
    SMAppService
  1. references/macos-background.md
    -
    NSBackgroundActivityScheduler
    、
    beginActivity
    、
    SMAppService

"My background task never runs / how do I test it"

"我的后台任务从未运行/如何测试"

  1. references/testing-and-debugging.md
    - lldb simulate commands, the states that gate execution
  2. references/anti-patterns.md
    - the usual causes
  1. references/testing-and-debugging.md
    - lldb模拟命令,控制执行的状态
  2. references/anti-patterns.md
    - 常见原因

"I'm hitting bugs or App Review issues"

"我遇到了Bug或App审核问题"

  1. references/anti-patterns.md
    - catches with before/after fixes
  1. references/anti-patterns.md
    - 问题及修复方案

Decision tree

决策树

Which background API should I use?

我应该使用哪个后台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
任务是否需要用户同意或中途输入?
  -> 后台运行并非正确选择,应切换到前台执行。

任务是否已在运行,仅需在应用进入后台时完成?
  -> 应用使用beginBackgroundTask / endBackgroundTask
  -> 应用扩展、watchOS使用ProcessInfo.performExpiringActivity

是否是用户发起的长任务,需显示进度并在后台继续?(iOS/iPadOS 26)
  -> BGContinuedProcessingTask

是否是必须在应用挂起/终止后仍能继续的大文件下载或上传?
  -> background URLSession

服务器是否需要通知应用有新内容?
  -> 后台(静默)推送 (apns-push-type: background, content-available: 1)

是否是来电邀请?
  -> PushKit + CallKit(每次推送都上报通话)

是否是周期性内容刷新,在用户打开应用前执行?
  -> BGAppRefreshTask

是否是可延迟的长时间维护/机器学习/清理任务?
  -> BGProcessingTask(可选requiresExternalPower / requiresNetworkConnectivity)

应用是否需要在后台持续播放音频或录制麦克风(包括锁屏状态)?
  -> audio UIBackgroundMode + 活跃AVAudioSession(.playback用于播放,.playAndRecord用于录制)  [background-audio.md]

应用是否需要因位置/BLE/VoIP持续运行?
  -> 声明匹配的UIBackgroundModes权限  [background-modes.md]

macOS上的可延迟重复维护任务?
  -> NSBackgroundActivityScheduler

macOS上防止关键非UI任务被休眠?
  -> ProcessInfo.beginActivity / performActivity

Which BGTask type?

选择哪种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
短内容刷新,系统在应用使用时段附近选择执行时间?
  -> BGAppRefreshTask          (UIBackgroundModes: fetch)

长时间维护任务,理想状态下在充电+联网时执行?
  -> BGProcessingTask          (UIBackgroundModes: processing; requiresExternalPower / requiresNetworkConnectivity)

用户触发的长任务,带进度UI,进入后台后继续运行?(iOS 26)
  -> BGContinuedProcessingTask (标题/副标题、进度、提交策略、可选.gpu)

健康研究数据的长时间处理?(iOS 17)
  -> BGHealthResearchTask

Core Instructions

核心指令

  • Never treat background execution as guaranteed. It is opportunistic and discretionary; design every feature with a foreground reconciliation path and never put correctness-critical logic solely in a background task.
  • Never register a
    BGTaskScheduler
    handler lazily, in view code, or after launch finishes. Register all handlers in
    App.init()
    /
    application(_:didFinishLaunchingWithOptions:)
    , because the system may launch the app directly into the background. (
    BGContinuedProcessingTask
    is the one exception - it registers dynamically on user intent.)
  • Never register the same task identifier twice - it crashes the app.
  • Never omit the expiration handler on a
    BGTask
    ; without one the system silently marks the task complete-and-unsuccessful. Set it, have it cancel work fast, and call
    setTaskCompleted(success:)
    exactly once.
  • Never forget to reschedule.
    BGTaskScheduler
    requests are one-shot; submit the next request as the first line of the launch handler.
  • Put
    requiresExternalPower
    /
    requiresNetworkConnectivity
    only on
    BGProcessingTaskRequest
    , never on app-refresh. Treat
    earliestBeginDate
    as a floor, not a schedule.
  • Never leave a
    beginBackgroundTask
    unbalanced. Call
    endBackgroundTask
    on both the success path and inside the expiration handler, idempotently (guard on
    .invalid
    ); an unbalanced assertion kills the app. Call
    beginBackgroundTask
    before starting the work, not at the end of the background-transition delegate.
  • Never trust
    backgroundTimeRemaining
    as a real budget - it is
    DBL_MAX
    in the foreground and advisory in the background. Plan for ~30 s and rely on the expiration handler.
  • Use
    beginBackgroundTask
    (apps) or
    performExpiringActivity
    (extensions, watchOS) only to finish work already running, never to start fresh long work or schedule future work.
  • Never use completion-handler convenience methods or
    dataTask
    on a background
    URLSession
    ; background sessions require a delegate. Create one session per identifier, store it, and recreate it at relaunch with the identical identifier and config.
  • Implement the full relaunch flow for background
    URLSession
    : store the handler from
    handleEventsForBackgroundURLSession
    , recreate the session, and call the stored handler from
    urlSessionDidFinishEvents(forBackgroundURLSession:)
    on the main thread. Move the file from
    didFinishDownloadingTo
    's
    location
    synchronously inside the callback.
  • For background uploads, use file-backed
    uploadTask(with:fromFile:)
    - data and stream uploads fail after the app exits.
  • Never send a silent push without
    apns-push-type: background
    (and
    apns-priority: 5
    ), and keep the
    aps
    dictionary to
    content-available
    only. Call the fetch completion handler within ~30 s. Treat silent push as throttled and coalesced, not reliable.
  • On iOS 13+, report an incoming call to CallKit on every VoIP push, or the system terminates the app and revokes VoIP-push privileges. Never use VoIP pushes for non-call data.
  • Never set
    allowsBackgroundLocationUpdates = true
    without the
    location
    background mode - it is a fatal error. Prefer significant-change / region monitoring over the continuous
    location
    mode.
  • Background audio needs both the
    audio
    mode and an active
    AVAudioSession
    with a background-capable category (
    .playback
    for playback,
    .playAndRecord
    /
    .record
    for recording-while-locked); the mode alone does nothing. Activate the session when audio begins (not at launch) and deactivate with
    .notifyOthersOnDeactivation
    . Always handle
    interruptionNotification
    (check
    .shouldResume
    before resuming) and
    routeChangeNotification
    (pause on
    .oldDeviceUnavailable
    ).
  • For mic capture, require permission with
    AVAudioApplication.requestRecordPermission()
    (iOS 17+) and declare
    NSMicrophoneUsageDescription
    - without the key the app crashes, and without permission capture returns silent zeroed samples, not an error. Install
    AVAudioEngine
    taps off the main actor (the closure runs on a realtime thread) and match
    AVAudioFile
    settings to the input node's format.
  • Declare
    UIBackgroundModes
    sparingly; App Review rejects unjustified modes. Prefer the lighter alternative.
  • Account for the user: a force-quit suppresses
    BGTaskScheduler
    , silent push, and background
    URLSession
    relaunch until the next manual launch. Read
    backgroundRefreshStatus
    (degrade on
    .denied
    , stay silent on
    .restricted
    ) and back off under Low Power Mode and elevated thermal state.
  • Do background-relevant setup (task registration, session recreation, dependency wiring) on a path that runs on every launch, not in
    .onAppear
    /
    .task
    - a background launch may never build the UI.
  • With scenes enabled, use
    sceneDidEnterBackground(_:)
    (not the deprecated
    applicationDidEnterBackground(_:)
    ); it has ~5 s to return.
  • On macOS use
    NSBackgroundActivityScheduler
    for deferrable maintenance and
    ProcessInfo.beginActivity
    /
    endActivity
    (balanced, or
    performActivity
    ) to control App Nap;
    performExpiringActivity
    does not exist on macOS.
  • Test background tasks on a real device with the lldb
    _simulateLaunchForTaskWithIdentifier:
    /
    _simulateExpirationForTaskWithIdentifier:
    commands - never ship a reference to them. Always test the expiration path.
  • 永远不要认为后台执行是有保障的。它是机会性和可酌情处理的;为每个功能设计前台协调路径,绝不要将正确性关键逻辑仅放在后台任务中。
  • 永远不要延迟注册
    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
    ——没有该键应用会崩溃,没有权限的话采集会返回静音的零样本,而非错误。在非主Actor上安装
    AVAudioEngine
    taps(闭包在实时线程运行),并使
    AVAudioFile
    设置与输入节点的格式匹配。
  • 谨慎声明
    UIBackgroundModes
    ;App审核会拒绝不合理的模式。优先选择更轻量的替代方案。
  • 考虑用户操作:强制退出会抑制
    BGTaskScheduler
    、静默推送和后台
    URLSession
    重启,直到下次手动启动。读取
    backgroundRefreshStatus
    (
    .denied
    时降级功能,
    .restricted
    时保持静默),并在低电量模式和高温状态下减少后台任务。
  • 在每次启动都会执行的流程中完成后台相关设置(任务注册、会话重建、依赖注入),不要在
    .onAppear
    /
    .task
    中设置——后台启动可能永远不会构建UI。
  • 启用场景后,使用
    sceneDidEnterBackground(_:)
    (而非已弃用的
    applicationDidEnterBackground(_:)
    );它有大约5秒的返回时间。
  • 在macOS上,使用
    NSBackgroundActivityScheduler
    处理可延迟的维护任务,使用
    ProcessInfo.beginActivity
    /
    endActivity
    (保持调用平衡,或使用
    performActivity
    )控制应用休眠;macOS上不存在
    performExpiringActivity
    。
  • 在真实设备上使用lldb的
    _simulateLaunchForTaskWithIdentifier:
    /
    _simulateExpirationForTaskWithIdentifier:
    命令测试后台任务——不要在发布版本中引用这些命令。始终测试过期路径。

Output Format

输出格式

If the user asks for a review, organize findings by file. For each issue:
  1. State the file and relevant line(s).
  2. Name the anti-pattern being replaced.
  3. Show a brief before/after code fix.
Skip files with no issues. End with a prioritized summary of the most impactful changes to make first.
If the user asks you to write or fix background-execution code, make the changes directly instead of returning a findings report.
Example output:
如果用户要求审核,按文件组织发现的问题。每个问题需包含:
  1. 说明文件及相关行号。
  2. 指出要替换的反模式。
  3. 展示简短的修复前后代码对比。
跳过无问题的文件。最后给出优先级排序的总结,列出最需要优先修改的关键问题。
如果用户要求编写或修复后台执行代码,直接修改代码,而非返回问题报告。
示例输出:

SyncManager.swift

SyncManager.swift

Line 22:
BGTaskScheduler
handler registered in
.onAppear
- never runs on a background launch.
swift
// 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)
    }
}
Line 48: missing expiration handler and
setTaskCompleted
- the app is killed at expiry.
swift
// 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)
}
第22行:
BGTaskScheduler
处理器在
.onAppear
中注册——后台启动时永远不会运行。
swift
// 修改前
.onAppear {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: id, using: nil) { ... }
}

// 修改后 - 在App.init() / didFinishLaunching中注册
init() {
    BGTaskScheduler.shared.register(forTaskWithIdentifier: id, using: nil) { task in
        self.handleRefresh(task: task as! BGAppRefreshTask)
    }
}
第48行:缺少过期处理器和
setTaskCompleted
调用——应用会在过期时被终止。
swift
// 修改前
func handleRefresh(task: BGAppRefreshTask) { refresh() }

// 修改后
func handleRefresh(task: BGAppRefreshTask) {
    scheduleNext()
    let op = RefreshOperation()
    task.expirationHandler = { op.cancel() }
    op.completionBlock = { task.setTaskCompleted(success: !op.isCancelled) }
    queue.addOperation(op)
}

Summary

总结

  1. Registration timing (high): move the handler to
    App.init()
    or it never fires on background launch.
  2. Completion contract (high): add the expiration handler and call
    setTaskCompleted
    exactly once.
End of example.
  1. 注册时机(高优先级): 将处理器移至
    App.init()
    ,否则后台启动时永远不会触发。
  2. 完成契约(高优先级): 添加过期处理器并准确调用一次
    setTaskCompleted
    。
示例结束。

References

参考文献

  • references/fundamentals.md
    - the execution model: foreground/background/suspended, system budgets, force-quit, user toggles, the five principles, the lifecycle and scene states, the "which API" map.
  • references/bg-task-scheduler.md
    -
    BackgroundTasks
    :
    BGAppRefreshTask
    ,
    BGProcessingTask
    ,
    BGContinuedProcessingTask
    (iOS 26),
    BGHealthResearchTask
    , registration, Info.plist keys, submit, expiration, errors.
  • references/task-assertions.md
    -
    beginBackgroundTask
    /
    endBackgroundTask
    ,
    backgroundTimeRemaining
    ,
    ProcessInfo.performExpiringActivity
    , assertions vs
    BGTaskScheduler
    .
  • references/background-url-session.md
    - background
    URLSession
    config, mandatory delegate, the relaunch /
    handleEventsForBackgroundURLSession
    flow, knobs, resume data.
  • references/background-push.md
    - silent/background push (payload, headers, handler, throttling), PushKit/VoIP + the CallKit requirement.
  • references/background-modes.md
    - the
    UIBackgroundModes
    matrix, background location, BLE/accessory/PTT, deprecated background fetch.
  • references/background-audio.md
    - background playback and recording:
    AVAudioSession
    categories/modes/options, recording while locked, mic permission, interruptions, route changes,
    AVAudioEngine
    taps and production gotchas.
  • references/swiftui-background-tasks.md
    -
    ScenePhase
    , the
    .backgroundTask
    scene modifier, async cancellation, scheduling vs handling.
  • references/macos-background.md
    -
    NSBackgroundActivityScheduler
    ,
    ProcessInfo.beginActivity
    /App Nap,
    SMAppService
    , cross-platform map.
  • references/testing-and-debugging.md
    - lldb simulate-launch/expiration,
    backgroundRefreshStatus
    , Low Power Mode, thermal state, what gates execution.
  • references/anti-patterns.md
    - common mistakes LLMs make when generating background-execution code.
  • 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
    taps及生产环境注意事项。
  • references/swiftui-background-tasks.md
    -
    ScenePhase
    、
    .backgroundTask
    场景修饰符、异步取消、调度与处理。
  • references/macos-background.md
    -
    NSBackgroundActivityScheduler
    、
    ProcessInfo.beginActivity
    /应用休眠、
    SMAppService
    、跨平台映射。
  • references/testing-and-debugging.md
    - lldb模拟启动/过期、
    backgroundRefreshStatus
    、低电量模式、高温状态、执行控制条件。
  • references/anti-patterns.md
    - 大语言模型生成后台执行代码时的常见错误。