{"id":"dd44aa8d-1a0c-40e6-adbb-30328fd72957","shortId":"ygpCF6","kind":"skill","title":"background-processing","tagline":"Schedule and execute background work on iOS using BGTaskScheduler. Use when registering BGAppRefreshTask for short background fetches, BGProcessingTask for long-running maintenance, BGContinuedProcessingTask (iOS 26+) for foreground-started work that continues in background, back","description":"# Background Processing\n\nRegister, schedule, and execute background work on iOS using the BackgroundTasks\nframework, background URLSession, and background push notifications.\n\n## Contents\n\n- [Info.plist Configuration](#infoplist-configuration)\n- [BGTaskScheduler Registration](#bgtaskscheduler-registration)\n- [BGAppRefreshTask Patterns](#bgapprefreshtask-patterns)\n- [BGProcessingTask Patterns](#bgprocessingtask-patterns)\n- [BGContinuedProcessingTask (iOS 26+)](#bgcontinuedprocessingtask-ios-26)\n- [Background URLSession Downloads](#background-urlsession-downloads)\n- [Background Push Triggers](#background-push-triggers)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Info.plist Configuration\n\nEvery task identifier **must** be declared in `Info.plist` under\n`BGTaskSchedulerPermittedIdentifiers`, or `submit(_:)` throws\n`BGTaskScheduler.Error.Code.notPermitted`.\n\n```xml\n<key>BGTaskSchedulerPermittedIdentifiers</key>\n<array>\n    <string>com.example.app.refresh</string>\n    <string>com.example.app.db-cleanup</string>\n    <string>com.example.app.export</string>\n</array>\n```\n\nAlso enable the required `UIBackgroundModes`:\n\n```xml\n<key>UIBackgroundModes</key>\n<array>\n    <string>fetch</string>       <!-- Required for BGAppRefreshTask -->\n    <string>processing</string>  <!-- Required for BGProcessingTask -->\n</array>\n```\n\nIn Xcode: target > Signing & Capabilities > Background Modes > enable\n\"Background fetch\" and \"Background processing\".\n\n## BGTaskScheduler Registration\n\nRegister handlers **before** app launch completes. In UIKit, register in\n`application(_:didFinishLaunchingWithOptions:)`. In SwiftUI, register in the\n`App` initializer.\n\n### UIKit Registration\n\n```swift\nimport BackgroundTasks\n\n@main\nclass AppDelegate: UIResponder, UIApplicationDelegate {\n    func application(\n        _ application: UIApplication,\n        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?\n    ) -> Bool {\n        BGTaskScheduler.shared.register(\n            forTaskWithIdentifier: \"com.example.app.refresh\",\n            using: nil  // nil = default background queue\n        ) { task in\n            self.handleAppRefresh(task: task as! BGAppRefreshTask)\n        }\n\n        BGTaskScheduler.shared.register(\n            forTaskWithIdentifier: \"com.example.app.db-cleanup\",\n            using: nil\n        ) { task in\n            self.handleDatabaseCleanup(task: task as! BGProcessingTask)\n        }\n\n        return true\n    }\n}\n```\n\n### SwiftUI Registration\n\n```swift\nimport SwiftUI\nimport BackgroundTasks\n\n@main\nstruct MyApp: App {\n    init() {\n        BGTaskScheduler.shared.register(\n            forTaskWithIdentifier: \"com.example.app.refresh\",\n            using: nil\n        ) { task in\n            BackgroundTaskManager.shared.handleAppRefresh(\n                task: task as! BGAppRefreshTask\n            )\n        }\n    }\n\n    var body: some Scene {\n        WindowGroup { ContentView() }\n    }\n}\n```\n\n## BGAppRefreshTask Patterns\n\nShort-lived tasks (~30 seconds) for fetching small data updates. The system\ndecides when to launch based on usage patterns.\n\n```swift\nfunc scheduleAppRefresh() {\n    let request = BGAppRefreshTaskRequest(\n        identifier: \"com.example.app.refresh\"\n    )\n    request.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)\n\n    do {\n        try BGTaskScheduler.shared.submit(request)\n    } catch {\n        print(\"Could not schedule app refresh: \\(error)\")\n    }\n}\n\nfunc handleAppRefresh(task: BGAppRefreshTask) {\n    // Schedule the next refresh before doing work\n    scheduleAppRefresh()\n\n    let fetchTask = Task {\n        do {\n            let data = try await APIClient.shared.fetchLatestFeed()\n            await FeedStore.shared.update(with: data)\n            task.setTaskCompleted(success: true)\n        } catch {\n            task.setTaskCompleted(success: false)\n        }\n    }\n\n    // CRITICAL: Handle expiration -- system can revoke time at any moment\n    task.expirationHandler = {\n        fetchTask.cancel()\n        task.setTaskCompleted(success: false)\n    }\n}\n```\n\n## BGProcessingTask Patterns\n\nLong-running tasks (minutes) for maintenance, data processing, or cleanup.\nRuns only when device is idle and (optionally) charging.\n\n```swift\nfunc scheduleProcessingTask() {\n    let request = BGProcessingTaskRequest(\n        identifier: \"com.example.app.db-cleanup\"\n    )\n    request.requiresNetworkConnectivity = false\n    request.requiresExternalPower = true\n    request.earliestBeginDate = Date(timeIntervalSinceNow: 60 * 60)\n\n    do {\n        try BGTaskScheduler.shared.submit(request)\n    } catch {\n        print(\"Could not schedule processing task: \\(error)\")\n    }\n}\n\nfunc handleDatabaseCleanup(task: BGProcessingTask) {\n    scheduleProcessingTask()\n\n    let cleanupTask = Task {\n        do {\n            try await DatabaseManager.shared.purgeExpiredRecords()\n            try await DatabaseManager.shared.rebuildIndexes()\n            task.setTaskCompleted(success: true)\n        } catch {\n            task.setTaskCompleted(success: false)\n        }\n    }\n\n    task.expirationHandler = {\n        cleanupTask.cancel()\n        task.setTaskCompleted(success: false)\n    }\n}\n```\n\n## BGContinuedProcessingTask (iOS 26+)\n\nA task initiated in the foreground by a user action that continues running in the\nbackground. The system displays progress via a Live Activity. Conforms to\n`ProgressReporting`.\n\n**Availability:** iOS 26.0+, iPadOS 26.0+\n\nUnlike `BGAppRefreshTask` and `BGProcessingTask`, this task starts immediately\nfrom the foreground. The system can terminate it under resource pressure,\nprioritizing tasks that report minimal progress first.\n\n```swift\nimport BackgroundTasks\n\nfunc startExport() {\n    // Register the task handler at app launch, not here.\n    // BGTaskScheduler requires registration before app launch completes.\n    let request = BGContinuedProcessingTaskRequest(\n        identifier: \"com.example.app.export\",\n        title: \"Exporting Photos\",\n        subtitle: \"Processing 247 items\"\n    )\n    // .queue: begin as soon as possible if can't run immediately\n    // .fail: fail submission if can't run immediately\n    request.strategy = .queue\n\n    do {\n        try BGTaskScheduler.shared.submit(request)\n    } catch {\n        print(\"Could not submit continued processing task: \\(error)\")\n    }\n}\n\nfunc performExport(task: BGContinuedProcessingTask) async {\n    let items = await PhotoLibrary.shared.itemsToExport()\n    let progress = task.progress\n    progress.totalUnitCount = Int64(items.count)\n\n    for (index, item) in items.enumerated() {\n        if Task.isCancelled { break }\n\n        await PhotoExporter.shared.export(item)\n        progress.completedUnitCount = Int64(index + 1)\n\n        // Update the user-facing title/subtitle\n        task.updateTitle(\n            \"Exporting Photos\",\n            subtitle: \"\\(index + 1) of \\(items.count) complete\"\n        )\n    }\n\n    task.setTaskCompleted(success: !Task.isCancelled)\n}\n```\n\nCheck whether the system supports the resources your task needs:\n\n```swift\nlet supported = BGTaskScheduler.supportedResources\nif supported.contains(.gpu) {\n    request.requiredResources = .gpu\n}\n```\n\n## Background URLSession Downloads\n\nUse `URLSessionConfiguration.background` for downloads that continue even after\nthe app is suspended or terminated. The system handles the transfer out of\nprocess.\n\n```swift\nclass DownloadManager: NSObject, URLSessionDownloadDelegate {\n    static let shared = DownloadManager()\n\n    private lazy var session: URLSession = {\n        let config = URLSessionConfiguration.background(\n            withIdentifier: \"com.example.app.background-download\"\n        )\n        config.isDiscretionary = true\n        config.sessionSendsLaunchEvents = true\n        return URLSession(configuration: config, delegate: self, delegateQueue: nil)\n    }()\n\n    func startDownload(from url: URL) {\n        let task = session.downloadTask(with: url)\n        task.earliestBeginDate = Date(timeIntervalSinceNow: 60)\n        task.resume()\n    }\n\n    func urlSession(\n        _ session: URLSession,\n        downloadTask: URLSessionDownloadTask,\n        didFinishDownloadingTo location: URL\n    ) {\n        // Move file from tmp before this method returns\n        let dest = FileManager.default.urls(\n            for: .documentDirectory, in: .userDomainMask\n        )[0].appendingPathComponent(\"download.dat\")\n        try? FileManager.default.moveItem(at: location, to: dest)\n    }\n\n    func urlSession(\n        _ session: URLSession,\n        task: URLSessionTask,\n        didCompleteWithError error: (any Error)?\n    ) {\n        if let error { print(\"Download failed: \\(error)\") }\n    }\n}\n```\n\nHandle app relaunch — store and invoke the system completion handler:\n\n```swift\n// In AppDelegate:\nfunc application(\n    _ application: UIApplication,\n    handleEventsForBackgroundURLSession identifier: String,\n    completionHandler: @escaping () -> Void\n) {\n    backgroundSessionCompletionHandler = completionHandler\n}\n\n// In URLSessionDelegate — call stored handler when events finish:\nfunc urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {\n    Task { @MainActor in\n        self.backgroundSessionCompletionHandler?()\n        self.backgroundSessionCompletionHandler = nil\n    }\n}\n```\n\n## Background Push Triggers\n\nSilent push notifications wake your app briefly to fetch new content. Set\n`content-available: 1` in the push payload.\n\n```json\n{ \"aps\": { \"content-available\": 1 }, \"custom-data\": \"new-messages\" }\n```\n\nHandle in AppDelegate:\n\n```swift\nfunc application(\n    _ application: UIApplication,\n    didReceiveRemoteNotification userInfo: [AnyHashable: Any],\n    fetchCompletionHandler completionHandler:\n        @escaping (UIBackgroundFetchResult) -> Void\n) {\n    Task {\n        do {\n            let hasNew = try await MessageStore.shared.fetchNewMessages()\n            completionHandler(hasNew ? .newData : .noData)\n        } catch {\n            completionHandler(.failed)\n        }\n    }\n}\n```\n\nEnable \"Remote notifications\" in Background Modes and register:\n\n```swift\nUIApplication.shared.registerForRemoteNotifications()\n```\n\n## Common Mistakes\n\n### 1. Missing Info.plist identifiers\n\n```swift\n// DON'T: Submit a task whose identifier isn't in BGTaskSchedulerPermittedIdentifiers\nlet request = BGAppRefreshTaskRequest(identifier: \"com.example.app.refresh\")\ntry BGTaskScheduler.shared.submit(request)  // Throws .notPermitted\n\n// DO: Add every identifier to Info.plist BGTaskSchedulerPermittedIdentifiers\n// <string>com.example.app.refresh</string>\n```\n\n### 2. Not calling setTaskCompleted(success:)\n\n```swift\n// DON'T: Return without marking completion -- system penalizes future scheduling\nfunc handleRefresh(task: BGAppRefreshTask) {\n    Task {\n        let data = try await fetchData()\n        await store.update(data)\n        // Missing: task.setTaskCompleted(success:)\n    }\n}\n\n// DO: Always call setTaskCompleted on every code path\nfunc handleRefresh(task: BGAppRefreshTask) {\n    let work = Task {\n        do {\n            let data = try await fetchData()\n            await store.update(data)\n            task.setTaskCompleted(success: true)\n        } catch {\n            task.setTaskCompleted(success: false)\n        }\n    }\n    task.expirationHandler = {\n        work.cancel()\n        task.setTaskCompleted(success: false)\n    }\n}\n```\n\n### 3. Ignoring the expiration handler\n\n```swift\n// DON'T: Assume your task will run to completion\nfunc handleCleanup(task: BGProcessingTask) {\n    Task { await heavyWork() }\n    // No expirationHandler -- system terminates ungracefully\n}\n\n// DO: Set expirationHandler to cancel work and mark completed\nfunc handleCleanup(task: BGProcessingTask) {\n    let work = Task { await heavyWork() }\n    task.expirationHandler = {\n        work.cancel()\n        task.setTaskCompleted(success: false)\n    }\n}\n```\n\n### 4. Scheduling too frequently\n\n```swift\n// DON'T: Request refresh every minute -- system throttles aggressively\nrequest.earliestBeginDate = Date(timeIntervalSinceNow: 60)\n\n// DO: Use reasonable intervals (15+ minutes for refresh)\nrequest.earliestBeginDate = Date(timeIntervalSinceNow: 15 * 60)\n// earliestBeginDate is a hint -- the system chooses actual launch time\n```\n\n### 5. Over-relying on background time\n\n```swift\n// DON'T: Start a 10-minute operation assuming it will finish\nfunc handleRefresh(task: BGAppRefreshTask) {\n    Task { await tenMinuteSync() }\n}\n\n// DO: Design work to be incremental and cancellable\nfunc handleRefresh(task: BGAppRefreshTask) {\n    let work = Task {\n        for batch in batches {\n            try Task.checkCancellation()\n            await processBatch(batch)\n            await saveBatchProgress(batch)\n        }\n        task.setTaskCompleted(success: true)\n    }\n    task.expirationHandler = {\n        work.cancel()\n        task.setTaskCompleted(success: false)\n    }\n}\n```\n\n## Review Checklist\n\n- [ ] All task identifiers listed in `BGTaskSchedulerPermittedIdentifiers`\n- [ ] Required `UIBackgroundModes` enabled (`fetch`, `processing`)\n- [ ] Tasks registered before app launch completes\n- [ ] `setTaskCompleted(success:)` called on every code path\n- [ ] `expirationHandler` set and cancels in-flight work\n- [ ] Next task scheduled inside the handler (re-schedule pattern)\n- [ ] `earliestBeginDate` uses reasonable intervals (15+ min for refresh)\n- [ ] Background URLSession uses delegate (not async/closures)\n- [ ] Background URLSession file moved in `didFinishDownloadingTo` before return\n- [ ] `handleEventsForBackgroundURLSession` stores and calls completion handler\n- [ ] Background push payload includes `content-available: 1`\n- [ ] `fetchCompletionHandler` called promptly with correct result\n- [ ] BGContinuedProcessingTask reports progress via `ProgressReporting`\n- [ ] Work is incremental and cancellation-safe (`Task.checkCancellation()`)\n- [ ] No blocking synchronous work in task handlers\n\n## References\n\n- See [references/background-task-patterns.md](references/background-task-patterns.md) for extended patterns, background\n  URLSession edge cases, debugging with simulated launches, and background push\n  best practices.\n- [BGTaskScheduler](https://sosumi.ai/documentation/backgroundtasks/bgtaskscheduler)\n- [BGAppRefreshTask](https://sosumi.ai/documentation/backgroundtasks/bgapprefreshtask)\n- [BGProcessingTask](https://sosumi.ai/documentation/backgroundtasks/bgprocessingtask)\n- [BGContinuedProcessingTask](https://sosumi.ai/documentation/backgroundtasks/bgcontinuedprocessingtask) (iOS 26+)\n- [BGContinuedProcessingTaskRequest](https://sosumi.ai/documentation/backgroundtasks/bgcontinuedprocessingtaskrequest) (iOS 26+)\n- [Using background tasks to update your app](https://sosumi.ai/documentation/uikit/using-background-tasks-to-update-your-app)\n- [Performing long-running tasks on iOS and iPadOS](https://sosumi.ai/documentation/backgroundtasks/performing-long-running-tasks-on-ios-and-ipados)","tags":["background","processing","swift","ios","skills","dpearson2699","accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills"],"capabilities":["skill","source-dpearson2699","skill-background-processing","topic-accessibility","topic-agent-skills","topic-ai-coding","topic-apple","topic-claude-code","topic-codex-skills","topic-cursor-skills","topic-ios","topic-ios-development","topic-liquid-glass","topic-localization","topic-mapkit"],"categories":["swift-ios-skills"],"synonyms":[],"warnings":[],"endpointUrl":"https://skills.sh/dpearson2699/swift-ios-skills/background-processing","protocol":"skill","transport":"skills-sh","auth":{"type":"none","details":{"cli":"npx skills add dpearson2699/swift-ios-skills","source_repo":"https://github.com/dpearson2699/swift-ios-skills","install_from":"skills.sh"}},"qualityScore":"0.700","qualityRationale":"deterministic score 0.70 from registry signals: · indexed on github topic:agent-skills · 599 github stars · SKILL.md body (14,941 chars)","verified":false,"liveness":"unknown","lastLivenessCheck":null,"agentReviews":{"count":0,"score_avg":null,"cost_usd_avg":null,"success_rate":null,"latency_p50_ms":null,"narrative_summary":null,"summary_updated_at":null},"enrichmentModel":"deterministic:skill-github:v1","enrichmentVersion":1,"enrichedAt":"2026-05-18T18:53:39.967Z","embedding":null,"createdAt":"2026-04-18T20:34:15.138Z","updatedAt":"2026-05-18T18:53:39.967Z","lastSeenAt":"2026-05-18T18:53:39.967Z","tsv":"'/documentation/backgroundtasks/bgapprefreshtask)':1259 '/documentation/backgroundtasks/bgcontinuedprocessingtask)':1267 '/documentation/backgroundtasks/bgcontinuedprocessingtaskrequest)':1273 '/documentation/backgroundtasks/bgprocessingtask)':1263 '/documentation/backgroundtasks/bgtaskscheduler)':1255 '/documentation/backgroundtasks/performing-long-running-tasks-on-ios-and-ipados)':1297 '/documentation/uikit/using-background-tasks-to-update-your-app)':1285 '0':724 '1':590,602,812,822,872,1205 '10':1077 '15':293,1046,1053,1174 '2':906 '247':525 '26':29,83,87,435,1269,1275 '26.0':465,467 '3':974 '30':265 '4':1024 '5':1065 '60':294,392,393,698,1041,1054 'action':445 'activ':459 'actual':1062 'add':899 'aggress':1037 'also':136 'alway':939 'anyhash':839 'ap':818 'apiclient.shared.fetchlatestfeed':327 'app':163,177,239,304,504,512,640,751,802,1142,1282 'appdeleg':186,762,831 'appendingpathcompon':725 'applic':170,190,191,764,765,834,835 'assum':982,1080 'async':565 'async/closures':1183 'avail':463,811,821,1204 'await':326,328,416,419,568,584,851,930,932,957,959,994,1017,1089,1112,1115 'back':39 'background':2,7,19,38,40,46,54,57,88,92,95,99,150,153,156,205,451,628,794,864,1070,1178,1184,1198,1239,1248,1277 'background-process':1 'background-push-trigg':98 'background-urlsession-download':91 'backgroundsessioncompletionhandl':773 'backgroundtask':52,183,235,496 'backgroundtaskmanager.shared.handleapprefresh':248 'base':278 'batch':1107,1109,1114,1117 'begin':528 'best':1250 'bgapprefreshtask':16,71,74,213,252,259,310,469,925,949,1087,1102,1256 'bgapprefreshtask-pattern':73 'bgapprefreshtaskrequest':287,890 'bgcontinuedprocessingtask':27,81,85,433,564,1212,1264 'bgcontinuedprocessingtask-io':84 'bgcontinuedprocessingtaskrequest':517,1270 'bgprocessingtask':21,76,79,226,354,409,471,992,1013,1260 'bgprocessingtask-pattern':78 'bgprocessingtaskrequest':381 'bgtaskschedul':12,66,69,158,508,1252 'bgtaskscheduler-registr':68 'bgtaskscheduler.error.code.notpermitted':129 'bgtaskscheduler.shared.register':198,214,241 'bgtaskscheduler.shared.submit':297,396,550,894 'bgtaskscheduler.supportedresources':622 'bgtaskschedulerpermittedidentifi':125,131,887,904,1133 'block':1226 'bodi':254 'bool':197 'break':583 'briefli':803 'call':777,908,940,1147,1195,1207 'cancel':1005,1098,1155,1222 'cancellation-saf':1221 'capabl':149 'case':1242 'catch':299,335,398,424,552,857,965 'charg':375 'check':609 'checklist':108,111,1127 'choos':1061 'class':185,654 'cleanup':134,217,366,384 'cleanuptask':412 'cleanuptask.cancel':429 'code':944,1150 'com.example.app.background':671 'com.example.app.db':133,216,383 'com.example.app.export':135,519 'com.example.app.refresh':132,200,243,289,892,905 'common':102,105,870 'common-mistak':104 'complet':165,514,605,758,917,988,1009,1144,1196 'completionhandl':770,774,842,853,858 'config':668,680 'config.isdiscretionary':673 'config.sessionsendslaunchevents':675 'configur':62,65,115,679 'conform':460 'content':60,807,810,820,1203 'content-avail':809,819,1202 'contentview':258 'continu':36,447,557,636 'correct':1210 'could':301,400,554 'critic':339 'custom':824 'custom-data':823 'data':270,324,331,363,825,928,934,955,961 'databasemanager.shared.purgeexpiredrecords':417 'databasemanager.shared.rebuildindexes':420 'date':291,390,696,1039,1051 'debug':1243 'decid':274 'declar':121 'default':204 'deleg':681,1181 'delegatequeu':683 'design':1092 'dest':718,732 'devic':370 'didcompletewitherror':739 'didfinishdownloadingto':706,1189 'didfinishlaunchingwithopt':171,193 'didreceiveremotenotif':837 'display':454 'documentdirectori':721 'download':90,94,630,634,672,747 'download.dat':726 'downloadmanag':655,661 'downloadtask':704 'earliestbegind':1055,1170 'edg':1241 'enabl':137,152,860,1136 'error':306,405,560,740,742,745,749 'escap':771,843 'even':637 'event':781 'everi':116,900,943,1033,1149 'execut':6,45 'expir':341,977 'expirationhandl':997,1003,1152 'export':521,598 'extend':1237 'face':595 'fail':538,539,748,859 'fals':338,353,386,427,432,968,973,1023,1125 'feedstore.shared.update':329 'fetch':20,143,154,268,805,1137 'fetchcompletionhandl':841,1206 'fetchdata':931,958 'fetchtask':320 'fetchtask.cancel':350 'file':710,1186 'filemanager.default.moveitem':728 'filemanager.default.urls':719 'finish':782,1083 'first':493 'flight':1158 'forbackgroundurlsess':785 'foreground':32,441,478 'foreground-start':31 'fortaskwithidentifi':199,215,242 'framework':53 'frequent':1027 'func':189,283,307,377,406,497,561,685,700,733,763,783,833,922,946,989,1010,1084,1099 'futur':920 'gpu':625,627 'handl':340,647,750,829 'handleapprefresh':308 'handlecleanup':990,1011 'handledatabasecleanup':407 'handleeventsforbackgroundurlsess':767,1192 'handler':161,502,759,779,978,1165,1197,1231 'handlerefresh':923,947,1085,1100 'hasnew':849,854 'heavywork':995,1018 'hint':1058 'identifi':118,288,382,518,768,875,883,891,901,1130 'idl':372 'ignor':975 'immedi':475,537,545 'import':182,232,234,495 'in-flight':1156 'includ':1201 'increment':1096,1219 'index':577,589,601 'info.plist':61,114,123,874,903 'infoplist':64 'infoplist-configur':63 'init':240 'initi':178,438 'insid':1163 'int64':574,588 'interv':1045,1173 'invok':755 'io':10,28,49,82,86,434,464,1268,1274,1292 'ipado':466,1294 'isn':884 'item':526,567,578,586 'items.count':575,604 'items.enumerated':580 'json':817 'launch':164,277,505,513,1063,1143,1246 'launchopt':194 'lazi':663 'let':285,319,323,379,411,515,566,570,620,659,667,690,717,744,848,888,927,950,954,1014,1103 'list':1131 'live':263,458 'locat':707,730 'long':24,357,1288 'long-run':23,356,1287 'main':184,236 'mainactor':789 'mainten':26,362 'mark':916,1008 'messag':828 'messagestore.shared.fetchnewmessages':852 'method':715 'min':1175 'minim':491 'minut':360,1034,1047,1078 'miss':873,935 'mistak':103,106,871 'mode':151,865 'moment':348 'move':709,1187 'must':119 'myapp':238 'need':618 'new':806,827 'new-messag':826 'newdata':855 'next':313,1160 'nil':202,203,219,245,684,793 'nodata':856 'notif':59,799,862 'notpermit':897 'nsobject':656 'oper':1079 'option':374 'over-r':1066 'path':945,1151 'pattern':72,75,77,80,260,281,355,1169,1238 'payload':816,1200 'penal':919 'perform':1286 'performexport':562 'photo':522,599 'photoexporter.shared.export':585 'photolibrary.shared.itemstoexport':569 'possibl':532 'practic':1251 'pressur':486 'print':300,399,553,746 'priorit':487 'privat':662 'process':3,41,144,157,364,403,524,558,652,1138 'processbatch':1113 'progress':455,492,571,1214 'progress.completedunitcount':587 'progress.totalunitcount':573 'progressreport':462,1216 'prompt':1208 'push':58,96,100,795,798,815,1199,1249 'queue':206,527,547 're':1167 're-schedul':1166 'reason':1044,1172 'refer':112,113,1232 'references/background-task-patterns.md':1234,1235 'refresh':305,314,1032,1049,1177 'regist':15,42,160,168,174,499,867,1140 'registr':67,70,159,180,230,510 'relaunch':752 'reli':1068 'remot':861 'report':490,1213 'request':286,298,380,397,516,551,889,895,1031 'request.earliestbegindate':290,389,1038,1050 'request.requiredresources':626 'request.requiresexternalpower':387 'request.requiresnetworkconnectivity':385 'request.strategy':546 'requir':139,509,1134 'resourc':485,615 'result':1211 'return':227,677,716,914,1191 'review':107,110,1126 'review-checklist':109 'revok':344 'run':25,358,367,448,536,544,986,1289 'safe':1223 'savebatchprogress':1116 'scene':256 'schedul':4,43,303,311,402,921,1025,1162,1168 'scheduleapprefresh':284,318 'scheduleprocessingtask':378,410 'second':266 'see':1233 'self':682 'self.backgroundsessioncompletionhandler':791,792 'self.handleapprefresh':209 'self.handledatabasecleanup':222 'session':665,702,735,786 'session.downloadtask':692 'set':808,1002,1153 'settaskcomplet':909,941,1145 'share':660 'short':18,262 'short-liv':261 'sign':148 'silent':797 'simul':1245 'skill' 'skill-background-processing' 'small':269 'soon':530 'sosumi.ai':1254,1258,1262,1266,1272,1284,1296 'sosumi.ai/documentation/backgroundtasks/bgapprefreshtask)':1257 'sosumi.ai/documentation/backgroundtasks/bgcontinuedprocessingtask)':1265 'sosumi.ai/documentation/backgroundtasks/bgcontinuedprocessingtaskrequest)':1271 'sosumi.ai/documentation/backgroundtasks/bgprocessingtask)':1261 'sosumi.ai/documentation/backgroundtasks/bgtaskscheduler)':1253 'sosumi.ai/documentation/backgroundtasks/performing-long-running-tasks-on-ios-and-ipados)':1295 'sosumi.ai/documentation/uikit/using-background-tasks-to-update-your-app)':1283 'source-dpearson2699' 'start':33,474,1075 'startdownload':686 'startexport':498 'static':658 'store':753,778,1193 'store.update':933,960 'string':769 'struct':237 'submiss':540 'submit':127,556,879 'subtitl':523,600 'success':333,337,352,422,426,431,607,910,937,963,967,972,1022,1119,1124,1146 'support':613,621 'supported.contains':624 'suspend':642 'swift':181,231,282,376,494,619,653,760,832,868,876,911,979,1028,1072 'swiftui':173,229,233 'synchron':1227 'system':273,342,453,480,612,646,757,918,998,1035,1060 'target':147 'task':117,207,210,211,220,223,224,246,249,250,264,309,321,359,404,408,413,437,473,488,501,559,563,617,691,737,788,846,881,924,926,948,952,984,991,993,1012,1016,1086,1088,1101,1105,1129,1139,1161,1230,1278,1290 'task.checkcancellation':1111,1224 'task.earliestbegindate':695 'task.expirationhandler':349,428,969,1019,1121 'task.iscancelled':582,608 'task.progress':572 'task.resume':699 'task.settaskcompleted':332,336,351,421,425,430,606,936,962,966,971,1021,1118,1123 'task.updatetitle':597 'tenminutesync':1090 'termin':482,644,999 'throttl':1036 'throw':128,896 'time':345,1064,1071 'timeintervalsincenow':292,391,697,1040,1052 'titl':520 'title/subtitle':596 'tmp':712 'topic-accessibility' 'topic-agent-skills' 'topic-ai-coding' 'topic-apple' 'topic-claude-code' 'topic-codex-skills' 'topic-cursor-skills' 'topic-ios' 'topic-ios-development' 'topic-liquid-glass' 'topic-localization' 'topic-mapkit' 'transfer':649 'tri':296,325,395,415,418,549,727,850,893,929,956,1110 'trigger':97,101,796 'true':228,334,388,423,674,676,964,1120 'uiapplic':192,766,836 'uiapplication.launchoptionskey':195 'uiapplication.shared.registerforremotenotifications':869 'uiapplicationdeleg':188 'uibackgroundfetchresult':844 'uibackgroundmod':140,142,1135 'uikit':167,179 'uirespond':187 'ungrac':1000 'unlik':468 'updat':271,591,1280 'url':688,689,694,708 'urlsess':55,89,93,629,666,678,701,703,734,736,787,1179,1185,1240 'urlsessionconfiguration.background':632,669 'urlsessiondeleg':776 'urlsessiondidfinishev':784 'urlsessiondownloaddeleg':657 'urlsessiondownloadtask':705 'urlsessiontask':738 'usag':280 'use':11,13,50,201,218,244,631,1043,1171,1180,1276 'user':444,594 'user-fac':593 'userdomainmask':723 'userinfo':838 'var':253,664 'via':456,1215 'void':772,845 'wake':800 'whether':610 'whose':882 'windowgroup':257 'withidentifi':670 'without':915 'work':8,34,47,317,951,1006,1015,1093,1104,1159,1217,1228 'work.cancel':970,1020,1122 'xcode':146 'xml':130,141","prices":[{"id":"f14377c8-1d94-44f7-b43a-4326eef03064","listingId":"dd44aa8d-1a0c-40e6-adbb-30328fd72957","amountUsd":"0","unit":"free","nativeCurrency":null,"nativeAmount":null,"chain":null,"payTo":null,"paymentMethod":"skill-free","isPrimary":true,"details":{"org":"dpearson2699","category":"swift-ios-skills","install_from":"skills.sh"},"createdAt":"2026-04-18T20:34:15.138Z"}],"sources":[{"listingId":"dd44aa8d-1a0c-40e6-adbb-30328fd72957","source":"github","sourceId":"dpearson2699/swift-ios-skills/background-processing","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/background-processing","isPrimary":false,"firstSeenAt":"2026-04-18T22:00:47.116Z","lastSeenAt":"2026-05-18T18:53:39.967Z"},{"listingId":"dd44aa8d-1a0c-40e6-adbb-30328fd72957","source":"skills_sh","sourceId":"dpearson2699/swift-ios-skills/background-processing","sourceUrl":"https://skills.sh/dpearson2699/swift-ios-skills/background-processing","isPrimary":true,"firstSeenAt":"2026-04-18T20:34:15.138Z","lastSeenAt":"2026-05-07T22:40:33.446Z"}],"details":{"listingId":"dd44aa8d-1a0c-40e6-adbb-30328fd72957","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"background-processing","github":{"repo":"dpearson2699/swift-ios-skills","stars":599,"topics":["accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills","ios","ios-development","liquid-glass","localization","mapkit","networking","storekit","swift","swift-concurrency","swiftdata","swiftui","widgetkit","xcode"],"license":"other","html_url":"https://github.com/dpearson2699/swift-ios-skills","pushed_at":"2026-04-26T21:04:17Z","description":"Agent Skills for iOS 26+, Swift 6.3, SwiftUI, and modern Apple frameworks","skill_md_sha":"afc4f45b52abc3ccd352ea6a707cfe578366ec39","skill_md_path":"skills/background-processing/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/background-processing"},"layout":"multi","source":"github","category":"swift-ios-skills","frontmatter":{"name":"background-processing","description":"Schedule and execute background work on iOS using BGTaskScheduler. Use when registering BGAppRefreshTask for short background fetches, BGProcessingTask for long-running maintenance, BGContinuedProcessingTask (iOS 26+) for foreground-started work that continues in background, background URLSession downloads, or background push notifications. Covers Info.plist configuration, expiration handling, task completion, and debugging with simulated launches."},"skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/background-processing"},"updatedAt":"2026-05-18T18:53:39.967Z"}}