{"id":"7e07c918-a290-4fc8-80ff-d255391a6921","shortId":"FaUG3L","kind":"skill","title":"swift-concurrency","tagline":"Resolve Swift concurrency compiler errors, adopt approachable concurrency (SE-0466), and write data-race-safe async code. Use when fixing Sendable conformance errors, actor isolation warnings, or strict concurrency diagnostics; when adopting default MainActor isolation, @concurre","description":"# Swift Concurrency\n\nReview, fix, and write concurrent Swift code targeting Swift 6.3+. Apply actor\nisolation, Sendable safety, and modern concurrency patterns with minimal\nbehavior changes.\n\n## Contents\n\n- [Triage Workflow](#triage-workflow)\n- [Swift 6.2 Language Changes](#swift-62-language-changes)\n- [Actor Isolation Rules](#actor-isolation-rules)\n- [Sendable Rules](#sendable-rules)\n- [Structured Concurrency Patterns](#structured-concurrency-patterns)\n- [Task Cancellation](#task-cancellation)\n- [Actor Reentrancy](#actor-reentrancy)\n- [AsyncSequence and AsyncStream](#asyncsequence-and-asyncstream)\n- [@Observable and Concurrency](#observable-and-concurrency)\n- [Synchronization Primitives](#synchronization-primitives)\n- [Common Mistakes](#common-mistakes)\n- [Review Checklist](#review-checklist)\n- [References](#references)\n\n## Triage Workflow\n\nWhen diagnosing a concurrency issue, follow this sequence:\n\n### Step 1: Capture context\n\n- Copy the exact compiler diagnostic(s) and the offending symbol(s).\n- Identify the project's concurrency settings:\n  - Swift language version (must be 6.2+).\n  - Whether approachable concurrency (default MainActor isolation) is enabled.\n  - Strict concurrency checking level (Complete / Targeted / Minimal).\n- Determine the current actor context of the code (`@MainActor`, custom `actor`,\n  `nonisolated`) and whether a default isolation mode is active.\n- Confirm whether the code is UI-bound or intended to run off the main actor.\n\n### Step 2: Apply the smallest safe fix\n\nPrefer edits that preserve existing behavior while satisfying data-race safety.\n\n| Situation | Recommended fix |\n|---|---|\n| UI-bound type | Annotate the type or relevant members with `@MainActor`. |\n| Protocol conformance on MainActor type | Use an isolated conformance: `extension Foo: @MainActor Proto`. |\n| Global / static state | Protect with `@MainActor` or move into an actor. |\n| Background work needed | Use a `@concurrent` async function on a `nonisolated` type. |\n| Sendable error | Prefer immutable value types. Add `Sendable` only when correct. |\n| Cross-isolation callback | Use `sending` parameters (SE-0430) for finer control. |\n\n### Step 3: Verify\n\n- Rebuild and confirm the diagnostic is resolved.\n- Check for new warnings introduced by the fix.\n- Ensure no unnecessary `@unchecked Sendable` or `nonisolated(unsafe)` was added.\n\n## Swift 6.2 Language Changes\n\nSwift 6.2 introduces \"approachable concurrency\" -- a set of language changes\nthat make concurrent code safer by default while reducing annotation burden.\n\n### SE-0466: Default MainActor Isolation\n\nWith the `-default-isolation MainActor` compiler flag (or the Xcode 26\n\"Approachable Concurrency\" build setting), all code in a module runs on\n`@MainActor` by default unless explicitly opted out.\n\n**Effect:** Eliminates most data-race safety errors for UI-bound code and\nglobal/static state without writing `@MainActor` everywhere.\n\n```swift\n// With default MainActor isolation enabled, these are implicitly @MainActor:\nfinal class StickerLibrary {\n    static let shared = StickerLibrary()  // safe -- on MainActor\n    var stickers: [Sticker] = []\n}\n\nfinal class StickerModel {\n    let photoProcessor = PhotoProcessor()\n    var selection: [PhotosPickerItem] = []\n}\n\n// Conformances are also implicitly isolated:\nextension StickerModel: Exportable {\n    func export() {\n        photoProcessor.exportAsPNG()\n    }\n}\n```\n\n**When to use:** Recommended for apps, scripts, and other executable targets\nwhere most code is UI-bound. Not recommended for library targets that should\nremain actor-agnostic.\n\n### SE-0461: nonisolated(nonsending)\n\nNonisolated async functions now stay on the caller's actor by default instead\nof hopping to the global concurrent executor. This is the\n`nonisolated(nonsending)` behavior.\n\n```swift\nclass PhotoProcessor {\n    func extractSticker(data: Data, with id: String?) async -> Sticker? {\n        // In Swift 6.2+, this runs on the caller's actor (e.g., MainActor)\n        // instead of hopping to a background thread.\n        // ...\n    }\n}\n\n@MainActor\nfinal class StickerModel {\n    let photoProcessor = PhotoProcessor()\n\n    func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {\n        guard let data = try await item.loadTransferable(type: Data.self) else {\n            return nil\n        }\n        // No data race -- photoProcessor stays on MainActor\n        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)\n    }\n}\n```\n\nUse `@concurrent` to explicitly request background execution when needed.\n\n### @concurrent Attribute\n\n`@concurrent` ensures a function always runs on the concurrent thread pool,\nfreeing the calling actor to run other tasks.\n\n```swift\nclass PhotoProcessor {\n    var cachedStickers: [String: Sticker] = [:]\n\n    func extractSticker(data: Data, with id: String) async -> Sticker {\n        if let sticker = cachedStickers[id] { return sticker }\n\n        let sticker = await Self.extractSubject(from: data)\n        cachedStickers[id] = sticker\n        return sticker\n    }\n\n    @concurrent\n    static func extractSubject(from data: Data) async -> Sticker {\n        // Expensive image processing -- runs on background thread pool\n        // ...\n    }\n}\n```\n\nTo move a function to a background thread:\n1. Ensure the containing type is `nonisolated` (or the function itself is).\n2. Add `@concurrent` to the function.\n3. Add `async` if not already asynchronous.\n4. Add `await` at call sites.\n\n```swift\nnonisolated struct PhotoProcessor {\n    @concurrent\n    func process(data: Data) async -> ProcessedPhoto? { /* ... */ }\n}\n\n// Caller:\nprocessedPhotos[item.id] = await PhotoProcessor().process(data: data)\n```\n\n### SE-0472: Task.immediate\n\n`Task.immediate` starts executing synchronously on the current actor before\nany suspension point, rather than being enqueued.\n\n```swift\nTask.immediate { await handleUserInput() }\n```\n\nUse for latency-sensitive work that should begin without delay. There is also\n`Task.immediateDetached` which combines immediate start with detached semantics.\n\n### SE-0475: Transactional Observation (Observations)\n\n`Observations { }` provides async observation of `@Observable` types via\n`AsyncSequence`, enabling transactional change tracking.\n\n```swift\nfor await _ in Observations { model.count } {\n    print(\"Count changed to \\(model.count)\")\n}\n```\n\n### Isolated Conformances\n\nA conformance that needs MainActor state is called an *isolated conformance*.\nThe compiler ensures it is only used in a matching isolation context.\n\n```swift\nprotocol Exportable {\n    func export()\n}\n\n// Isolated conformance: only usable on MainActor\nextension StickerModel: @MainActor Exportable {\n    func export() {\n        photoProcessor.exportAsPNG()\n    }\n}\n\n@MainActor\nstruct ImageExporter {\n    var items: [any Exportable]\n\n    mutating func add(_ item: StickerModel) {\n        items.append(item)  // OK -- ImageExporter is on MainActor\n    }\n}\n```\n\nIf `ImageExporter` were `nonisolated`, adding a `StickerModel` would fail:\n\"Main actor-isolated conformance of 'StickerModel' to 'Exportable' cannot be\nused in nonisolated context.\"\n\n### Clock Epochs\n\n`ContinuousClock` and `SuspendingClock` now expose `.epoch` (SE-0473), enabling instant comparison and conversion between clock types.\n\n```swift\nlet continuous = ContinuousClock()\nlet elapsed = continuous.now - continuous.epoch  // Duration since system boot\n```\n\n## Actor Isolation Rules\n\n1. All mutable shared state MUST be protected by an actor or global actor.\n2. `@MainActor` for all UI-touching code. No exceptions.\n3. Use `nonisolated` only for methods that access immutable (`let`) properties\n   or are pure computations.\n4. Use `@concurrent` to explicitly move work off the caller's actor.\n5. Never use `nonisolated(unsafe)` unless you have proven internal\n   synchronization and exhausted all other options.\n6. Never add manual locks (`NSLock`, `DispatchSemaphore`) inside actors.\n\n## Sendable Rules\n\n1. Value types (structs, enums) are automatically `Sendable` when all stored\n   properties are `Sendable`.\n2. Actors are implicitly `Sendable`.\n3. `@MainActor` classes are implicitly `Sendable`. Do NOT add redundant\n   `Sendable` conformance.\n4. Non-actor classes: must be `final` with all stored properties `let` and\n   `Sendable`.\n5. `@unchecked Sendable` is a last resort. Document why the compiler cannot\n   prove safety.\n6. Use `sending` parameters (SE-0430) for finer-grained isolation control.\n7. Use `@preconcurrency import` only for third-party libraries you cannot\n   modify. Plan to remove it.\n\n## Structured Concurrency Patterns\n\n### Async Defer\n\n`defer` blocks can now contain `await` (SE-0493). Use for async cleanup — closing connections, flushing buffers, or releasing resources that require an async call.\n\n```swift\nfunc fetchData() async throws -> Data {\n    let connection = try await openConnection()\n    defer { await connection.close() }\n    return try await connection.read()\n}\n```\n\n**Task:** Unstructured, inherits caller context.\n```swift\nTask { await doWork() }\n```\n\n**Task.detached:** No inherited context. Use only when you explicitly need to\nbreak isolation inheritance.\n\n**Task.immediate:** Starts immediately on current actor. Use for\nlatency-sensitive work.\n```swift\nTask.immediate { await handleUserInput() }\n```\n\n**async let:** Fixed number of concurrent operations.\n```swift\nasync let a = fetchA()\nasync let b = fetchB()\nlet result = try await (a, b)\n```\n\n**TaskGroup:** Dynamic number of concurrent operations.\n```swift\ntry await withThrowingTaskGroup(of: Item.self) { group in\n    for id in ids {\n        group.addTask { try await fetch(id) }\n    }\n    for try await item in group { process(item) }\n}\n```\n\n## Task Cancellation\n\n- Cancellation is cooperative. Check `Task.isCancelled` or call\n  `try Task.checkCancellation()` in loops.\n- Use `.task` modifier in SwiftUI -- it handles cancellation on view disappear.\n- Use `withTaskCancellationHandler` for cleanup.\n- Cancel stored tasks in `deinit` or `onDisappear`.\n\n## Actor Reentrancy\n\nActors are reentrant. State can change across suspension points.\n\n```swift\n// WRONG: State may change during await\nactor Counter {\n    var count = 0\n    func increment() async {\n        let current = count\n        await someWork()\n        count = current + 1  // BUG: count may have changed\n    }\n}\n\n// CORRECT: Mutate synchronously, no reentrancy risk\nactor Counter {\n    var count = 0\n    func increment() { count += 1 }\n}\n```\n\n## AsyncSequence and AsyncStream\n\nUse `AsyncStream` to bridge callback/delegate APIs:\n\n```swift\nlet stream = AsyncStream<Location> { continuation in\n    let delegate = LocationDelegate { location in\n        continuation.yield(location)\n    }\n    continuation.onTermination = { _ in delegate.stop() }\n    delegate.start()\n}\n```\n\nUse `withCheckedContinuation` / `withCheckedThrowingContinuation` for\nsingle-value callbacks. Resume exactly once.\n\n## @Observable and Concurrency\n\n- `@Observable` classes should be `@MainActor` for view models.\n- Use `@State` to own an `@Observable` instance (replaces `@StateObject`).\n- Use `Observations { }` (SE-0475) for async observation of `@Observable`\n  properties as an `AsyncSequence`.\n\n## Synchronization Primitives\n\nWhen actors are not the right fit — synchronous access, performance-critical\npaths, or bridging C/ObjC — use low-level synchronization primitives:\n\n- **`Mutex<Value>`** (iOS 18+, `Synchronization` module): Preferred lock for\n  new code. Stores protected state inside the lock. `withLock { }` pattern.\n- **`OSAllocatedUnfairLock`** (iOS 16+, `os` module): Use when targeting\n  older iOS versions. Supports ownership assertions for debugging.\n- **`Atomic<Value>`** (iOS 18+, `Synchronization` module): Lock-free atomics\n  for simple counters and flags. Requires explicit memory ordering.\n\n**Key rule:** Never put locks inside actors (double synchronization), and never\nhold a lock across `await` (deadlock risk). See\n[references/synchronization-primitives.md](references/synchronization-primitives.md) for full API details, code examples,\nand a decision guide for choosing locks vs actors.\n\n## Common Mistakes\n\n1. **Blocking the main actor.** Heavy computation on `@MainActor` freezes UI.\n   Move to a `@concurrent` function.\n2. **Unnecessary @MainActor.** Network layers, data processing, and model code\n   do not need `@MainActor`. Only UI-touching code does.\n3. **Actors for stateless code.** No mutable state means no actor needed. Use a\n   plain struct or function.\n4. **Actors for immutable data.** Use a `Sendable` struct, not an actor.\n5. **Task.detached without good reason.** Loses priority, task-local values,\n   and cancellation propagation.\n6. **Forgetting task cancellation.** Store `Task` references and cancel them, or\n   use the `.task` view modifier.\n7. **Retain cycles in Tasks.** Use `[weak self]` when capturing `self` in\n   long-lived stored tasks.\n8. **Semaphores in async context.** `DispatchSemaphore.wait()` in async code\n   will deadlock. Use structured concurrency instead.\n9. **Split isolation.** Mixing `@MainActor` and `nonisolated` properties in one\n   type. Isolate the entire type consistently.\n10. **MainActor.run instead of static isolation.** Prefer `@MainActor func`\n    over `await MainActor.run { }`.\n11. **Using GCD APIs.** Never use DispatchQueue, DispatchGroup, DispatchSemaphore, or any GCD API. Use async/await, actors, and TaskGroups instead. GCD has no data-race safety guarantees.\n\n## Review Checklist\n\n- [ ] All mutable shared state is actor-isolated\n- [ ] No data races (no unprotected cross-isolation access)\n- [ ] Tasks are cancelled when no longer needed\n- [ ] No blocking calls on `@MainActor`\n- [ ] No manual locks inside actors\n- [ ] `Sendable` conformance is correct (no unjustified `@unchecked`)\n- [ ] Actor reentrancy is handled (no state assumptions across awaits)\n- [ ] `@preconcurrency` imports are documented with removal plan\n- [ ] Heavy work uses `@concurrent`, not `@MainActor`\n- [ ] `.task` modifier used in SwiftUI instead of manual Task management\n\n## References\n\n- See [references/concurrency-patterns.md](references/concurrency-patterns.md) for detailed approachable concurrency patterns,\n  patterns, and migration examples.\n- See [references/approachable-concurrency.md](references/approachable-concurrency.md) for the approachable concurrency\n  mode quick-reference guide.\n- See [references/swiftui-concurrency.md](references/swiftui-concurrency.md) for SwiftUI-specific concurrency\n  guidance.\n- See [references/synchronization-primitives.md](references/synchronization-primitives.md) for Mutex, OSAllocatedUnfairLock,\n  and guidance on choosing locks vs actors.","tags":["swift","concurrency","ios","skills","dpearson2699","accessibility","agent-skills","ai-coding","apple","claude-code","codex-skills","cursor-skills"],"capabilities":["skill","source-dpearson2699","skill-swift-concurrency","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/swift-concurrency","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.684","qualityRationale":"deterministic score 0.68 from registry signals: · indexed on github topic:agent-skills · 468 github stars · SKILL.md body (14,658 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-04-22T00:53:44.941Z","embedding":null,"createdAt":"2026-04-18T22:01:20.556Z","updatedAt":"2026-04-22T00:53:44.941Z","lastSeenAt":"2026-04-22T00:53:44.941Z","tsv":"'-0430':318,1077 '-0461':503 '-0466':13,376 '-0472':742 '-0473':910 '-0475':787,1389 '-0493':1113 '-62':77 '0':1297,1324 '1':152,691,934,1012,1308,1328,1513 '10':1657 '11':1669 '16':1443 '18':1425,1459 '2':230,703,948,1026,1529 '26':391 '3':323,709,958,1031,1549 '4':716,973,1043,1567 '5':985,1058,1579 '6':1001,1072,1593 '6.2':73,177,351,355,546 '6.3':52 '7':1084,1609 '8':1626 '9':1641 'access':965,1409,1714 'across':1283,1489,1746 'activ':212 'actor':28,54,81,85,105,108,196,203,228,286,500,515,553,627,751,888,931,944,947,984,1009,1027,1046,1176,1275,1277,1293,1320,1402,1481,1510,1517,1550,1559,1568,1578,1684,1704,1731,1739,1817 'actor-agnost':499 'actor-isol':887,1703 'actor-isolation-rul':84 'actor-reentr':107 'ad':349,881 'add':305,704,710,717,867,1003,1039 'adopt':9,36 'agnost':501 'alreadi':714 'also':464,777 'alway':617 'annot':255,373 'api':1337,1498,1672,1681 'app':478 'appli':53,231 'approach':10,179,357,392,1777,1789 'assert':1454 'assumpt':1745 'async':20,293,507,542,574,646,673,711,731,793,1104,1116,1128,1133,1187,1195,1199,1300,1391,1629,1633 'async/await':1683 'asynchron':715 'asyncsequ':110,114,799,1329,1398 'asyncsequence-and-asyncstream':113 'asyncstream':112,116,1331,1333,1341 'atom':1457,1465 'attribut':612 'automat':1018 'await':581,596,657,718,736,762,806,1111,1139,1142,1146,1155,1185,1206,1217,1229,1234,1292,1304,1490,1667,1747 'b':1201,1208 'background':287,561,607,680,689 'begin':772 'behavior':64,241,531 'block':1107,1514,1723 'boot':930 'bound':220,253,421,490 'break':1168 'bridg':1335,1415 'buffer':1121 'bug':1309 'build':394 'burden':374 'c/objc':1416 'cachedstick':636,651,661 'call':626,720,824,1129,1248,1724 'callback':313,1362 'callback/delegate':1336 'caller':513,551,733,982,1151 'cancel':101,104,1241,1242,1260,1268,1591,1596,1601,1717 'cannot':895,1069,1095 'captur':153,1618 'chang':65,75,80,353,363,802,812,1282,1290,1313 'check':188,332,1245 'checklist':135,138,1697 'choos':1507,1814 'class':441,454,533,565,633,1033,1047,1370 'cleanup':1117,1267 'clock':901,917 'close':1118 'code':21,49,200,216,367,397,422,486,955,1432,1500,1538,1547,1553,1634 'combin':780 'common':129,132,1511 'common-mistak':131 'comparison':913 'compil':7,158,386,829,1068 'complet':190 'comput':972,1519 'concurr':3,6,11,33,40,42,47,60,94,98,119,123,146,170,180,187,292,358,366,393,524,603,611,613,621,666,705,726,975,1102,1192,1213,1368,1527,1639,1758,1778,1790,1803 'confirm':213,327 'conform':26,264,271,462,816,818,827,846,890,1042,1733 'connect':1119,1137 'connection.close':1143 'connection.read':1147 'consist':1656 'contain':694,1110 'content':66 'context':154,197,839,900,1152,1160,1630 'continu':921,1342 'continuation.ontermination':1351 'continuation.yield':1349 'continuous.epoch':926 'continuous.now':925 'continuousclock':903,922 'control':321,1083 'convers':915 'cooper':1244 'copi':155 'correct':309,1314,1735 'count':811,1296,1303,1306,1310,1323,1327 'counter':1294,1321,1468 'critic':1412 'cross':311,1712 'cross-isol':310,1711 'current':195,750,1175,1302,1307 'custom':202 'cycl':1611 'data':17,245,414,537,538,579,589,598,599,641,642,660,671,672,729,730,739,740,1135,1534,1571,1692,1707 'data-rac':244,413,1691 'data-race-saf':16 'data.self':584 'deadlock':1491,1636 'debug':1456 'decis':1504 'default':37,181,208,370,377,383,405,432,517 'default-isol':382 'defer':1105,1106,1141 'deinit':1272 'delay':774 'deleg':1345 'delegate.start':1354 'delegate.stop':1353 'detach':784 'detail':1499,1776 'determin':193 'diagnos':144 'diagnost':34,159,329 'disappear':1263 'dispatchgroup':1676 'dispatchqueu':1675 'dispatchsemaphor':1007,1677 'dispatchsemaphore.wait':1631 'document':1065,1751 'doubl':1482 'dowork':1156 'durat':927 'dynam':1210 'e.g':554 'edit':237 'effect':410 'elaps':924 'elimin':411 'els':585 'enabl':185,435,800,911 'enqueu':759 'ensur':340,614,692,830 'entir':1654 'enum':1016 'epoch':902,908 'error':8,27,300,417 'everywher':429 'exact':157,1364 'exampl':1501,1783 'except':957 'execut':482,608,746 'executor':525 'exhaust':997 'exist':240 'expens':675 'explicit':407,605,977,1165,1472 'export':469,471,842,844,854,856,864,894 'expos':907 'extens':272,467,851 'extractstick':536,571,640 'extractsubject':669 'fail':885 'fetch':1230 'fetcha':1198 'fetchb':1202 'fetchdata':1132 'final':440,453,564,1050 'finer':320,1080 'finer-grain':1079 'fit':1407 'fix':24,44,235,250,339,1189 'flag':387,1470 'flush':1120 'follow':148 'foo':273 'forget':1594 'free':624,1464 'freez':1522 'full':1497 'func':470,535,570,639,668,727,843,855,866,1131,1298,1325,1665 'function':294,508,616,686,700,708,1528,1566 'gcd':1671,1680,1688 'global':276,523,946 'global/static':424 'good':1582 'grain':1081 'group':1221,1237 'group.addtask':1227 'guarante':1695 'guard':577 'guid':1505,1795 'guidanc':1804,1812 'handl':1259,1742 'handleuserinput':763,1186 'heavi':1518,1755 'hold':1486 'hop':520,558 'id':540,644,652,662,1224,1226,1231 'identifi':166 'imag':676 'imageexport':860,873,878 'immedi':781,1173 'immut':302,966,1570 'implicit':438,465,1029,1035 'import':1087,1749 'increment':1299,1326 'inherit':1150,1159,1170 'insid':1008,1436,1480,1730 'instanc':1383 'instant':912 'instead':518,556,1640,1659,1687,1766 'intend':222 'intern':994 'introduc':336,356 'io':1424,1442,1450,1458 'isol':29,39,55,82,86,183,209,270,312,379,384,434,466,815,826,838,845,889,932,1082,1169,1643,1652,1662,1705,1713 'issu':147 'item':572,862,868,871,1235,1239 'item.id':735 'item.itemidentifier':601 'item.loadtransferable':582 'item.self':1220 'items.append':870 'key':1475 'languag':74,79,173,352,362 'language-chang':78 'last':1063 'latenc':767,1180 'latency-sensit':766,1179 'layer':1533 'let':444,456,567,578,649,655,920,923,967,1055,1136,1188,1196,1200,1203,1301,1339,1344 'level':189,1420 'librari':494,1093 'live':1623 'local':1588 'locat':1347,1350 'locationdeleg':1346 'lock':1005,1429,1438,1463,1479,1488,1508,1729,1815 'lock-fre':1462 'long':1622 'long-liv':1621 'longer':1720 'loop':1252 'lose':1584 'low':1419 'low-level':1418 'main':227,886,1516 'mainactor':38,182,201,262,266,274,281,378,385,403,428,433,439,449,555,563,594,821,850,853,858,876,949,1032,1373,1521,1531,1542,1645,1664,1726,1760 'mainactor.run':1658,1668 'make':365 'manag':1770 'manual':1004,1728,1768 'match':837 'may':1289,1311 'mean':1557 'member':260 'memori':1473 'method':963 'migrat':1782 'minim':63,192 'mistak':130,133,1512 'mix':1644 'mode':210,1791 'model':1376,1537 'model.count':809,814 'modern':59 'modifi':1096,1255,1608,1762 'modul':400,1427,1445,1461 'move':283,684,978,1524 'must':175,939,1048 'mutabl':936,1555,1699 'mutat':865,1315 'mutex':1423,1809 'need':289,610,820,1166,1541,1560,1721 'network':1532 'never':986,1002,1477,1485,1673 'new':334,1431 'nil':587 'non':1045 'non-actor':1044 'nonisol':204,297,346,504,506,529,697,723,880,899,960,988,1647 'nonsend':505,530 'nslock':1006 'number':1190,1211 'observ':117,121,789,790,791,794,796,808,1366,1369,1382,1387,1392,1394 'observable-and-concurr':120 'offend':163 'ok':872 'older':1449 'ondisappear':1274 'one':1650 'openconnect':1140 'oper':1193,1214 'opt':408 'option':1000 'order':1474 'os':1444 'osallocatedunfairlock':1441,1810 'ownership':1453 'paramet':316,1075 'parti':1092 'path':1413 'pattern':61,95,99,1103,1440,1779,1780 'perform':1411 'performance-crit':1410 'photoprocessor':457,458,534,568,569,591,634,725,737 'photoprocessor.exportaspng':472,857 'photoprocessor.extractsticker':597 'photospickeritem':461,573 'plain':1563 'plan':1097,1754 'point':755,1285 'pool':623,682 'preconcurr':1086,1748 'prefer':236,301,1428,1663 'preserv':239 'primit':125,128,1400,1422 'print':810 'prioriti':1585 'process':677,728,738,1238,1535 'processedphoto':732,734 'project':168 'propag':1592 'properti':968,1023,1054,1395,1648 'protect':279,941,1434 'proto':275 'protocol':263,841 'prove':1070 'proven':993 'provid':792 'pure':971 'put':1478 'quick':1793 'quick-refer':1792 'race':18,246,415,590,1693,1708 'rather':756 'reason':1583 'rebuild':325 'recommend':249,476,492 'reduc':372 'redund':1040 'reentranc':106,109,1276,1318,1740 'reentrant':1279 'refer':139,140,1599,1771,1794 'references/approachable-concurrency.md':1785,1786 'references/concurrency-patterns.md':1773,1774 'references/swiftui-concurrency.md':1797,1798 'references/synchronization-primitives.md':1494,1495,1806,1807 'releas':1123 'relev':259 'remain':498 'remov':1099,1753 'replac':1384 'request':606 'requir':1126,1471 'resolv':4,331 'resort':1064 'resourc':1124 'result':1204 'resum':1363 'retain':1610 'return':586,595,653,664,1144 'review':43,134,137,1696 'review-checklist':136 'right':1406 'risk':1319,1492 'rule':83,87,89,92,933,1011,1476 'run':224,401,548,618,629,678 'safe':19,234,447 'safer':368 'safeti':57,247,416,1071,1694 'satisfi':243 'script':479 'se':12,317,375,502,741,786,909,1076,1112,1388 'see':1493,1772,1784,1796,1805 'select':460 'self':1616,1619 'self.extractsubject':658 'semant':785 'semaphor':1627 'send':315,1074 'sendabl':25,56,88,91,299,306,344,1010,1019,1025,1030,1036,1041,1057,1060,1574,1732 'sendable-rul':90 'sensit':768,1181 'sequenc':150 'set':171,360,395 'share':445,937,1700 'simpl':1467 'sinc':928 'singl':1360 'single-valu':1359 'site':721 'situat':248 'skill' 'skill-swift-concurrency' 'smallest':233 'somework':1305 'source-dpearson2699' 'specif':1802 'split':1642 'start':745,782,1172 'state':278,425,822,938,1280,1288,1378,1435,1556,1701,1744 'stateless':1552 'stateobject':1385 'static':277,443,667,1661 'stay':510,592 'step':151,229,322 'sticker':451,452,543,576,638,647,650,654,656,663,665,674 'stickerlibrari':442,446 'stickermodel':455,468,566,852,869,883,892 'store':1022,1053,1269,1433,1597,1624 'stream':1340 'strict':32,186 'string':541,637,645 'struct':724,859,1015,1564,1575 'structur':93,97,1101,1638 'structured-concurrency-pattern':96 'support':1452 'suspendingclock':905 'suspens':754,1284 'swift':2,5,41,48,51,72,76,172,350,354,430,532,545,632,722,760,804,840,919,1130,1153,1183,1194,1215,1286,1338 'swift-concurr':1 'swiftui':1257,1765,1801 'swiftui-specif':1800 'symbol':164 'synchron':124,127,747,995,1316,1399,1408,1421,1426,1460,1483 'synchronization-primit':126 'system':929 'target':50,191,483,495,1448 'task':100,103,631,1148,1154,1240,1254,1270,1587,1595,1598,1606,1613,1625,1715,1761,1769 'task-cancel':102 'task-loc':1586 'task.checkcancellation':1250 'task.detached':1157,1580 'task.immediate':743,744,761,1171,1184 'task.immediatedetached':778 'task.iscancelled':1246 'taskgroup':1209,1686 'third':1091 'third-parti':1090 'thread':562,622,681,690 'throw':575,1134 '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' 'touch':954,1546 'track':803 'transact':788,801 'tri':580,1138,1145,1205,1216,1228,1233,1249 'triag':67,70,141 'triage-workflow':69 'type':254,257,267,298,304,583,695,797,918,1014,1651,1655 'ui':219,252,420,489,953,1523,1545 'ui-bound':218,251,419,488 'ui-touch':952,1544 'uncheck':343,1059,1738 'unjustifi':1737 'unless':406,990 'unnecessari':342,1530 'unprotect':1710 'unsaf':347,989 'unstructur':1149 'usabl':848 'use':22,268,290,314,475,602,764,834,897,959,974,987,1073,1085,1114,1161,1177,1253,1264,1332,1355,1377,1386,1417,1446,1561,1572,1604,1614,1637,1670,1674,1682,1757,1763 'valu':303,1013,1361,1589 'var':450,459,635,861,1295,1322 'verifi':324 'version':174,1451 'via':798 'view':1262,1375,1607 'vs':1509,1816 'warn':30,335 'weak':1615 'whether':178,206,214 'withcheckedcontinu':1356 'withcheckedthrowingcontinu':1357 'withlock':1439 'without':426,773,1581 'withtaskcancellationhandl':1265 'withthrowingtaskgroup':1218 'work':288,769,979,1182,1756 'workflow':68,71,142 'would':884 'write':15,46,427 'wrong':1287 'xcode':390","prices":[{"id":"6f1ee521-ffcd-4d3c-8050-55d2f9786ab5","listingId":"7e07c918-a290-4fc8-80ff-d255391a6921","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-18T22:01:20.556Z"}],"sources":[{"listingId":"7e07c918-a290-4fc8-80ff-d255391a6921","source":"github","sourceId":"dpearson2699/swift-ios-skills/swift-concurrency","sourceUrl":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/swift-concurrency","isPrimary":false,"firstSeenAt":"2026-04-18T22:01:20.556Z","lastSeenAt":"2026-04-22T00:53:44.941Z"}],"details":{"listingId":"7e07c918-a290-4fc8-80ff-d255391a6921","quickStartSnippet":null,"exampleRequest":null,"exampleResponse":null,"schema":null,"openapiUrl":null,"agentsTxtUrl":null,"citations":[],"useCases":[],"bestFor":[],"notFor":[],"kindDetails":{"org":"dpearson2699","slug":"swift-concurrency","github":{"repo":"dpearson2699/swift-ios-skills","stars":468,"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-21T19:26:16Z","description":"Agent Skills for iOS 26+, Swift 6.3, SwiftUI, and modern Apple frameworks","skill_md_sha":"95876e9315e3c10a67f91a0518831093c6984d1e","skill_md_path":"skills/swift-concurrency/SKILL.md","default_branch":"main","skill_tree_url":"https://github.com/dpearson2699/swift-ios-skills/tree/main/skills/swift-concurrency"},"layout":"multi","source":"github","category":"swift-ios-skills","frontmatter":{"name":"swift-concurrency","description":"Resolve Swift concurrency compiler errors, adopt approachable concurrency (SE-0466), and write data-race-safe async code. Use when fixing Sendable conformance errors, actor isolation warnings, or strict concurrency diagnostics; when adopting default MainActor isolation, @concurrent, nonisolated(nonsending), or Task.immediate; when designing actor-based architectures, structured concurrency with TaskGroup, or background work offloading; or when migrating from @preconcurrency to full Swift 6 strict concurrency."},"skills_sh_url":"https://skills.sh/dpearson2699/swift-ios-skills/swift-concurrency"},"updatedAt":"2026-04-22T00:53:44.941Z"}}