Token导航 LogoToken导航TokenDH.com
开发需要联网github未标认证来源可访问许可证需确认审计通过

background-processing后台处理

Agent Skill

background-processing 用于处理 GitHub 仓库、Issue、Pull Request 和代码协作信息,适合在 Codex、Claude、Cursor、Gemini CLI 中需要围绕仓库状态、代码变更或协作事项进行整理时使用。可结合来源仓库、安装命令和原始 README 继续核验具体用法。安装前建议确认权限范围、维护状态,以及是否会触发联网、命令执行或文件读写。

总安装

27,456

周安装

1,098

GitHub Stars

488

下载量

8,888
CodexClaudeCursorGemini CLI

安装说明

本站只整理中文说明和来源信息,不托管安装包,也不代用户安装。

GitHub

来源数

2

许可证

unknown

最后核验

2026-05-01

来源状态

来源可访问

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:background-processing(后台处理)
来源仓库:https://github.com/dpearson2699/swift-ios-skills
仓库路径:skills/background-processing
安装命令:
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill background-processing
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。该命令会通过 npx skills 从第三方来源获取 Skill;本站只展示命令,不托管安装包,也不自动执行。

skills.shnpx skills
npx skills add https://github.com/dpearson2699/swift-ios-skills --skill background-processing

简介

background-processing 注册和管理 iOS 后台任务,使用 BackgroundTasks 框架执行延后操作。

  • 它支持 URLSession 下载和推送触发,适用于数据同步和离线内容更新。
  • 使用时需在 Info.plist 声明任务标识符,否则会抛出权限错误。
  • 安装前应检查设备是否支持后台执行,并避免滥用导致电池消耗过快。
  • 适用宿主包括 Codex、Claude、Cursor、Gemini CLI,接入前应确认版本、权限和运行环境要求。

SKILL.md

Background Processing

Register, schedule, and execute background work on iOS using the BackgroundTasks framework, background URLSession, and background push notifications.

Contents

Info.plist Configuration

Every task identifier must be declared in Info.plist under BGTaskSchedulerPermittedIdentifiers, or submit(_:) throws BGTaskScheduler.Error.Code.notPermitted.

<key>BGTaskSchedulerPermittedIdentifiers</key>
<array>
    <string>com.example.app.refresh</string>
    <string>com.example.app.db-cleanup</string>
    <string>com.example.app.export</string>
</array>

Also enable the required UIBackgroundModes:

<key>UIBackgroundModes</key>
<array>
    <string>fetch</string>       <!-- Required for BGAppRefreshTask -->
    <string>processing</string>  <!-- Required for BGProcessingTask -->
</array>

In Xcode: target > Signing & Capabilities > Background Modes > enable "Background fetch" and "Background processing".

BGTaskScheduler Registration

Register handlers before app launch completes. In UIKit, register in application(_:didFinishLaunchingWithOptions:). In SwiftUI, register in the App initializer.

UIKit Registration

import BackgroundTasks

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: "com.example.app.refresh",
            using: nil  // nil = default background queue
        ) { task in
            self.handleAppRefresh(task: task as! BGAppRefreshTask)
        }

        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: "com.example.app.db-cleanup",
            using: nil
        ) { task in
            self.handleDatabaseCleanup(task: task as! BGProcessingTask)
        }

        return true
    }
}

SwiftUI Registration

import SwiftUI
import BackgroundTasks

@main
struct MyApp: App {
    init() {
        BGTaskScheduler.shared.register(
            forTaskWithIdentifier: "com.example.app.refresh",
            using: nil
        ) { task in
            BackgroundTaskManager.shared.handleAppRefresh(
                task: task as! BGAppRefreshTask
            )
        }
    }

    var body: some Scene {
        WindowGroup { ContentView() }
    }
}

BGAppRefreshTask Patterns

Short-lived tasks (~30 seconds) for fetching small data updates. The system decides when to launch based on usage patterns.

func scheduleAppRefresh() {
    let request = BGAppRefreshTaskRequest(
        identifier: "com.example.app.refresh"
    )
    request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)

    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        print("Could not schedule app refresh: \(error)")
    }
}

func handleAppRefresh(task: BGAppRefreshTask) {
    // Schedule the next refresh before doing work
    scheduleAppRefresh()

    let fetchTask = Task {
        do {
            let data = try await APIClient.shared.fetchLatestFeed()
            await FeedStore.shared.update(with: data)
            task.setTaskCompleted(success: true)
        } catch {
            task.setTaskCompleted(success: false)
        }
    }

    // CRITICAL: Handle expiration -- system can revoke time at any moment
    task.expirationHandler = {
        fetchTask.cancel()
        task.setTaskCompleted(success: false)
    }
}

BGProcessingTask Patterns

Long-running tasks (minutes) for maintenance, data processing, or cleanup. Runs only when device is idle and (optionally) charging.

func scheduleProcessingTask() {
    let request = BGProcessingTaskRequest(
        identifier: "com.example.app.db-cleanup"
    )
    request.requiresNetworkConnectivity = false
    request.requiresExternalPower = true
    request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 60)

    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        print("Could not schedule processing task: \(error)")
    }
}

func handleDatabaseCleanup(task: BGProcessingTask) {
    scheduleProcessingTask()

    let cleanupTask = Task {
        do {
            try await DatabaseManager.shared.purgeExpiredRecords()
            try await DatabaseManager.shared.rebuildIndexes()
            task.setTaskCompleted(success: true)
        } catch {
            task.setTaskCompleted(success: false)
        }
    }

    task.expirationHandler = {
        cleanupTask.cancel()
        task.setTaskCompleted(success: false)
    }
}

BGContinuedProcessingTask (iOS 26+)

A task initiated in the foreground by a user action that continues running in the background. The system displays progress via a Live Activity. Conforms to ProgressReporting.

Availability: iOS 26.0+, iPadOS 26.0+

Unlike BGAppRefreshTask and BGProcessingTask, this task starts immediately from the foreground. The system can terminate it under resource pressure, prioritizing tasks that report minimal progress first.

import BackgroundTasks

func startExport() {
    // Register the task handler at app launch, not here.
    // BGTaskScheduler requires registration before app launch completes.
    let request = BGContinuedProcessingTaskRequest(
        identifier: "com.example.app.export",
        title: "Exporting Photos",
        subtitle: "Processing 247 items"
    )
    // .queue: begin as soon as possible if can't run immediately
    // .fail: fail submission if can't run immediately
    request.strategy = .queue

    do {
        try BGTaskScheduler.shared.submit(request)
    } catch {
        print("Could not submit continued processing task: \(error)")
    }
}

func performExport(task: BGContinuedProcessingTask) async {
    let items = await PhotoLibrary.shared.itemsToExport()
    let progress = task.progress
    progress.totalUnitCount = Int64(items.count)

    for (index, item) in items.enumerated() {
        if Task.isCancelled { break }

        await PhotoExporter.shared.export(item)
        progress.completedUnitCount = Int64(index + 1)

        // Update the user-facing title/subtitle
        task.updateTitle(
            "Exporting Photos",
            subtitle: "\(index + 1) of \(items.count) complete"
        )
    }

    task.setTaskCompleted(success: !Task.isCancelled)
}

Check whether the system supports the resources your task needs:

let supported = BGTaskScheduler.supportedResources
if supported.contains(.gpu) {
    request.requiredResources = .gpu
}

Background URLSession Downloads

Use URLSessionConfiguration.background for downloads that continue even after the app is suspended or terminated. The system handles the transfer out of process.

class DownloadManager: NSObject, URLSessionDownloadDelegate {
    static let shared = DownloadManager()

    private lazy var session: URLSession = {
        let config = URLSessionConfiguration.background(
            withIdentifier: "com.example.app.background-download"
        )
        config.isDiscretionary = true
        config.sessionSendsLaunchEvents = true
        return URLSession(configuration: config, delegate: self, delegateQueue: nil)
    }()

    func startDownload(from url: URL) {
        let task = session.downloadTask(with: url)
        task.earliestBeginDate = Date(timeIntervalSinceNow: 60)
        task.resume()
    }

    func urlSession(
        _ session: URLSession,
        downloadTask: URLSessionDownloadTask,
        didFinishDownloadingTo location: URL
    ) {
        // Move file from tmp before this method returns
        let dest = FileManager.default.urls(
            for: .documentDirectory, in: .userDomainMask
        )[0].appendingPathComponent("download.dat")
        try? FileManager.default.moveItem(at: location, to: dest)
    }

    func urlSession(
        _ session: URLSession,
        task: URLSessionTask,
        didCompleteWithError error: (any Error)?
    ) {
        if let error { print("Download failed: \(error)") }
    }
}

Handle app relaunch — store and invoke the system completion handler:

// In AppDelegate:
func application(
    _ application: UIApplication,
    handleEventsForBackgroundURLSession identifier: String,
    completionHandler: @escaping () -> Void
) {
    backgroundSessionCompletionHandler = completionHandler
}

// In URLSessionDelegate — call stored handler when events finish:
func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
    Task { @MainActor in
        self.backgroundSessionCompletionHandler?()
        self.backgroundSessionCompletionHandler = nil
    }
}

Background Push Triggers

Silent push notifications wake your app briefly to fetch new content. Set content-available: 1 in the push payload.

{ "aps": { "content-available": 1 }, "custom-data": "new-messages" }

Handle in AppDelegate:

func application(
    _ application: UIApplication,
    didReceiveRemoteNotification userInfo: [AnyHashable: Any],
    fetchCompletionHandler completionHandler:
        @escaping (UIBackgroundFetchResult) -> Void
) {
    Task {
        do {
            let hasNew = try await MessageStore.shared.fetchNewMessages()
            completionHandler(hasNew ? .newData : .noData)
        } catch {
            completionHandler(.failed)
        }
    }
}

Enable "Remote notifications" in Background Modes and register:

UIApplication.shared.registerForRemoteNotifications()

Common Mistakes

1. Missing Info.plist identifiers

// DON'T: Submit a task whose identifier isn't in BGTaskSchedulerPermittedIdentifiers
let request = BGAppRefreshTaskRequest(identifier: "com.example.app.refresh")
try BGTaskScheduler.shared.submit(request)  // Throws .notPermitted

// DO: Add every identifier to Info.plist BGTaskSchedulerPermittedIdentifiers
// <string>com.example.app.refresh</string>

2. Not calling setTaskCompleted(success:)

// DON'T: Return without marking completion -- system penalizes future scheduling
func handleRefresh(task: BGAppRefreshTask) {
    Task {
        let data = try await fetchData()
        await store.update(data)
        // Missing: task.setTaskCompleted(success:)
    }
}

// DO: Always call setTaskCompleted on every code path
func handleRefresh(task: BGAppRefreshTask) {
    let work = Task {
        do {
            let data = try await fetchData()
            await store.update(data)
            task.setTaskCompleted(success: true)
        } catch {
            task.setTaskCompleted(success: false)
        }
    }
    task.expirationHandler = {
        work.cancel()
        task.setTaskCompleted(success: false)
    }
}

3. Ignoring the expiration handler

// DON'T: Assume your task will run to completion
func handleCleanup(task: BGProcessingTask) {
    Task { await heavyWork() }
    // No expirationHandler -- system terminates ungracefully
}

// DO: Set expirationHandler to cancel work and mark completed
func handleCleanup(task: BGProcessingTask) {
    let work = Task { await heavyWork() }
    task.expirationHandler = {
        work.cancel()
        task.setTaskCompleted(success: false)
    }
}

4. Scheduling too frequently

// DON'T: Request refresh every minute -- system throttles aggressively
request.earliestBeginDate = Date(timeIntervalSinceNow: 60)

// DO: Use reasonable intervals (15+ minutes for refresh)
request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)
// earliestBeginDate is a hint -- the system chooses actual launch time

5. Over-relying on background time

// DON'T: Start a 10-minute operation assuming it will finish
func handleRefresh(task: BGAppRefreshTask) {
    Task { await tenMinuteSync() }
}

// DO: Design work to be incremental and cancellable
func handleRefresh(task: BGAppRefreshTask) {
    let work = Task {
        for batch in batches {
            try Task.checkCancellation()
            await processBatch(batch)
            await saveBatchProgress(batch)
        }
        task.setTaskCompleted(success: true)
    }
    task.expirationHandler = {
        work.cancel()
        task.setTaskCompleted(success: false)
    }
}

Review Checklist

  • All task identifiers listed in BGTaskSchedulerPermittedIdentifiers
  • Required UIBackgroundModes enabled (fetch, processing)
  • Tasks registered before app launch completes
  • setTaskCompleted(success:) called on every code path
  • expirationHandler set and cancels in-flight work
  • Next task scheduled inside the handler (re-schedule pattern)
  • earliestBeginDate uses reasonable intervals (15+ min for refresh)
  • Background URLSession uses delegate (not async/closures)
  • Background URLSession file moved in didFinishDownloadingTo before return
  • handleEventsForBackgroundURLSession stores and calls completion handler
  • Background push payload includes content-available: 1
  • fetchCompletionHandler called promptly with correct result
  • BGContinuedProcessingTask reports progress via ProgressReporting
  • Work is incremental and cancellation-safe (Task.checkCancellation())
  • No blocking synchronous work in task handlers

References

适合场景

01

用户想查找某类 Agent Skill 时

02

需要根据任务场景推荐可安装能力包时

03

需要对比不同来源的安装命令和来源信息时

能力概览

能力 1

按任务关键词查找相关 Skills

能力 2

展示可复制的安装命令

能力 3

保留来源站点、仓库和原始说明,方便继续核验

能力 4

展示第三方安全扫描或审计结果

安装后应在对应宿主中按原始 README 的触发条件使用;具体调用方式请以来源页面和 README 为准。

平台分布

Codex

32.4%
按下载量换算2,880

Claude

32.39%
按下载量换算2,879

Cursor

18.42%
按下载量换算1,637

Gemini CLI

9.42%
按下载量换算837

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。当前只有一个来源,正式发布前建议补源仓库或其他目录站核验。

来源信息

继续浏览同类 Skills