/concurrency
Swift 6.2 concurrency updates including default MainActor inference, @concurrent for background work, isolated conformances, and approachable concurrency migration. Use when adopting Swift 6.2 concurrency features or fixing data-race errors.
$ npx -y skills add rshankras/claude-code-apple-skills --skill concurrency --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/concurrency
Context preview
The summary Claude sees to decide when to auto-load this skill.
Swift 6.2 concurrency updates including default MainActor inference, @concurrent for background work, isolated conformances, and approachable concurrency migration. Use when adopting Swift 6.2 concurrency features or fixing data-race errors.
SKILL.md
concurrency.SKILL.mdname: swift-concurrency-updates
description: Swift 6.2 concurrency updates including default MainActor inference, @concurrent for background work, isolated conformances, and approachable concurrency migration. Use when adopting Swift 6.2 concurrency features or fixing data-race errors.
allowed-tools: [Read, Glob, Grep]
last_verified: 2026-07-16
review_by: 2027-06-22
os_version: iOS 27 / macOS 27
Swift 6.2 Concurrency Updates
Swift 6.2 introduces "Approachable Concurrency" -- a set of changes that make strict concurrency dramatically easier to adopt. Code runs on `@MainActor` by default, async functions stay on the calling actor, and you explicitly request background execution with `@concurrent`.
This skill covers only the Swift 6.2 specific changes. For general concurrency patterns (actors, TaskGroup, AsyncSequence, Sendable, cancellation), see the `swift/concurrency-patterns` skill.
When This Skill Activates
- User is adopting Swift 6.2 concurrency features
- User asks about default MainActor inference or the "infer main actor" build setting
- User encounters data-race errors that Swift 6.2 resolves
- User asks about `@concurrent`, isolated conformances, or approachable concurrency
- User wants to migrate from Swift 6.0/6.1 strict concurrency to 6.2
- User asks how async functions behave differently in Swift 6.2
- User needs to offload CPU-intensive work to a background thread in Swift 6.2
What Changed in Swift 6.2 vs Before
Swift 6.2 Changes at a Glance
| Feature | Before (6.0/6.1) | After (6.2) | |---------|------------------|-------------| | Default isolation | Nothing inferred; manual `@MainActor` everywhere | Opt-in mode infers `@MainActor` on everything | | Async function execution | Hops to generic concurrent executor | Stays on calling actor | | `@MainActor` type conforming to protocol | Compiler error for non-isolated protocols | Isolated conformances: `@MainActor Protocol` | | Background execution | `Task.detached` or manual nonisolated functions | `@concurrent` attribute | | Global/static mutable state | Required `@MainActor` annotation or Sendable | Default MainActor mode handles it automatically |
---
1. Async Functions Stay on the Calling Actor
In Swift 6.2, async functions without specific actor isolation stay on whatever actor called them, instead of hopping to the generic concurrent executor as in 6.0/6.1 -- eliminating a common source of data-race errors with no code changes required.
---
2. Default MainActor Inference Mode
An opt-in build setting that makes all code implicitly `@MainActor` unless explicitly opted out with `nonisolated`.
Enabling It
**Xcode:** Build Settings > Swift Compiler - Concurrency > "Default Actor Isolation" > "MainActor"
**Swift Package Manager:**
.executableTarget(
name: "MyApp",
swiftSettings: [
.defaultIsolation(MainActor.self)
]
)With this enabled, app-level types no longer need explicit `@MainActor` annotations -- including global/static mutable state, which otherwise needs an explicit `@MainActor static let ...`.
When to Use Default MainActor Inference
| Target Type | Recommended? | Reason | |-------------|-------------|--------| | App target | Yes | Apps are UI-driven; most code belongs on MainActor | | Script / executable | Yes | Scripts are sequential; MainActor default is natural | | Library / framework | No | Libraries must not impose actor isolation on consumers | | Package plugin | No | Same reasoning as libraries |
Opting Out with nonisolated
When a type or function genuinely needs to run off the main actor, mark it `nonisolated`:
nonisolated struct ImageProcessor {
func processImage(_ data: Data) -> UIImage {
// Runs on any thread, not MainActor
...
}
}---
3. Isolated Conformances
Isolated conformances let a `@MainActor` type conform to a protocol that does not require actor isolation, using `extension Type: @MainActor ProtocolName`. Before Swift 6.2, this produced a compiler error about the main actor-isolated conformance crossing an isolation boundary.
protocol Exportable {
func export()
}
@MainActor
final class StickerModel {
let processor: PhotoProcessor
func doExport() { processor.exportAsPNG() }
}
// ✅ Swift 6.2 -- isolated conformance
extension StickerModel: @MainActor Exportable {
func export() {
processor.exportAsPNG() // Works: conformance is MainActor-isolated
}
}The conformance can only be used from a context that shares the same isolation domain:
// ✅ Used within @MainActor context -- OK
@MainActor
func exportAll(_ items: [any Exportable]) {
for item in items { item.export() }
}
// ❌ Used outside @MainActor -- compile error
nonisolated func exportAll(_ items: [any Exportable]) {
for item in items {
item.export() // Error: isolated conformance not available here
}
}---
4. @concurrent -- Explicit Background Execution
`@concurrent` explicitly offloads a function to the background thread pool, replacing the pattern of using `Task.detached` for compute-intensive operations.
nonisolated struct ImageProcessor {
@concurrent
func resize(image: Data, to size: CGSize) async -> Data {
// Runs on background thread pool
...
}
}
// Caller (on MainActor):
let resized = await ImageProcessor().resize(image: data, to: targetSize)Steps to Offload Work
1. Make the containing type `nonisolated` (for structs/classes; actors are already isolated) 2. Add `@concurrent` to the function 3. Make the function `async` 4. Callers use `await`
@concurrent vs Task.detached vs actor
| Mechanism | Use Case | Structured? | |-----------|----------|-------------| | `@concurrent` | Single function that must run on background thread | Yes (inherits task context) | | `Task.detached` | Fire-and-forget background work, no structured parent | No | | `actor` | Shared mutable state
Read more
name: swift-concurrency-updates description: Swift 6.2 concurrency updates including default MainActor inference, @concurrent for background work, isolated conformances, and approachable concurrency migration. Use when adopting Swift 6.2 concurrency features or fixing data-race errors. allowed-tools: [Read, Glob, Grep] last_verified: 2026-07-16 review_by: 2027-06-22 os_version: iOS 27 / macOS 27
Swift 6.2 Concurrency Updates
Swift 6.2 introduces "Approachable Concurrency" -- a set of changes that make strict concurrency dramatically easier to adopt. Code runs on `@MainActor` by default, async functions stay on the calling actor, and you explicitly request background execution with `@concurrent`.
This skill covers only the Swift 6.2 specific changes. For general concurrency patterns (actors, TaskGroup, AsyncSequence, Sendable, cancellation), see the `swift/concurrency-patterns` skill.
When This Skill Activates
- User is adopting Swift 6.2 concurrency features
- User asks about default MainActor inference or the "infer main actor" build setting
- User encounters data-race errors that Swift 6.2 resolves
- User asks about `@concurrent`, isolated conformances, or approachable concurrency
- User wants to migrate from Swift 6.0/6.1 strict concurrency to 6.2
- User asks how async functions behave differently in Swift 6.2
- User needs to offload CPU-intensive work to a background thread in Swift 6.2
What Changed in Swift 6.2 vs Before
Swift 6.2 Changes at a Glance
| Feature | Before (6.0/6.1) | After (6.2) | |---------|------------------|-------------| | Default isolation | Nothing inferred; manual `@MainActor` everywhere | Opt-in mode infers `@MainActor` on everything | | Async function execution | Hops to generic concurrent executor | Stays on calling actor | | `@MainActor` type conforming to protocol | Compiler error for non-isolated protocols | Isolated conformances: `@MainActor Protocol` | | Background execution | `Task.detached` or manual nonisolated functions | `@concurrent` attribute | | Global/static mutable state | Required `@MainActor` annotation or Sendable | Default MainActor mode handles it automatically |
---
1. Async Functions Stay on the Calling Actor
In Swift 6.2, async functions without specific actor isolation stay on whatever actor called them, instead of hopping to the generic concurrent executor as in 6.0/6.1 -- eliminating a common source of data-race errors with no code changes required.
---
2. Default MainActor Inference Mode
An opt-in build setting that makes all code implicitly `@MainActor` unless explicitly opted out with `nonisolated`.
Enabling It
**Xcode:** Build Settings > Swift Compiler - Concurrency > "Default Actor Isolation" > "MainActor"
**Swift Package Manager:**
.executableTarget(
name: "MyApp",
swiftSettings: [
.defaultIsolation(MainActor.self)
]
)With this enabled, app-level types no longer need explicit `@MainActor` annotations -- including global/static mutable state, which otherwise needs an explicit `@MainActor static let ...`.
When to Use Default MainActor Inference
| Target Type | Recommended? | Reason | |-------------|-------------|--------| | App target | Yes | Apps are UI-driven; most code belongs on MainActor | | Script / executable | Yes | Scripts are sequential; MainActor default is natural | | Library / framework | No | Libraries must not impose actor isolation on consumers | | Package plugin | No | Same reasoning as libraries |
Opting Out with nonisolated
When a type or function genuinely needs to run off the main actor, mark it `nonisolated`:
nonisolated struct ImageProcessor {
func processImage(_ data: Data) -> UIImage {
// Runs on any thread, not MainActor
...
}
}---
3. Isolated Conformances
Isolated conformances let a `@MainActor` type conform to a protocol that does not require actor isolation, using `extension Type: @MainActor ProtocolName`. Before Swift 6.2, this produced a compiler error about the main actor-isolated conformance crossing an isolation boundary.
protocol Exportable {
func export()
}
@MainActor
final class StickerModel {
let processor: PhotoProcessor
func doExport() { processor.exportAsPNG() }
}
// ✅ Swift 6.2 -- isolated conformance
extension StickerModel: @MainActor Exportable {
func export() {
processor.exportAsPNG() // Works: conformance is MainActor-isolated
}
}The conformance can only be used from a context that shares the same isolation domain:
// ✅ Used within @MainActor context -- OK
@MainActor
func exportAll(_ items: [any Exportable]) {
for item in items { item.export() }
}
// ❌ Used outside @MainActor -- compile error
nonisolated func exportAll(_ items: [any Exportable]) {
for item in items {
item.export() // Error: isolated conformance not available here
}
}---
4. @concurrent -- Explicit Background Execution
`@concurrent` explicitly offloads a function to the background thread pool, replacing the pattern of using `Task.detached` for compute-intensive operations.
nonisolated struct ImageProcessor {
@concurrent
func resize(image: Data, to size: CGSize) async -> Data {
// Runs on background thread pool
...
}
}
// Caller (on MainActor):
let resized = await ImageProcessor().resize(image: data, to: targetSize)Steps to Offload Work
1. Make the containing type `nonisolated` (for structs/classes; actors are already isolated) 2. Add `@concurrent` to the function 3. Make the function `async` 4. Callers use `await`
@concurrent vs Task.detached vs actor
| Mechanism | Use Case | Structured? | |-----------|----------|-------------| | `@concurrent` | Single function that must run on background thread | Yes (inherits task context) | | `Task.detached` | Fire-and-forget background work, no structured parent | No | | `actor` | Shared mutable state
A collection of Claude Code skills for iOS, macOS, watchOS, visionOS, and Apple platform development. These skills help you plan and build apps, maintain code quality, ensure HIG compliance, and guide you from idea to App Store.
Repo: rshankras/claude-code-apple-skills
Other skills on rshankras-apple-skills.
- /app-store
App Store optimization and marketing skills for descriptions, screenshots, keywords, review responses, and comprehensive promotional strategy. Use when user needs help with App Store presence, ASO, marketing, or customer communication.
Open skill - /ad-attribution
Privacy-preserving ad measurement with AdAttributionKit (SKAdNetwork's successor) — install and re-engagement attribution, conversion-value strategy under crowd anonymity, and end-to-end postback testing. Use when running paid acquisition beyond Apple Ads, measuring
Open skill - /app-description-writer
Generate compelling App Store descriptions that convert browsers into users. Use when writing initial descriptions, improving existing copy, or drafting promotional text and What's New for a major update.
Open skill - /apple-search-ads
Apple Search Ads campaign strategy for indie developers — paid acquisition, keyword bidding, budget planning, and ROAS optimization. Use when user asks about running ads, paid user acquisition, or Apple Search Ads campaigns.
Open skill - /iap-finalizer
Take a one-time in-app purchase from MISSING_METADATA to READY_TO_SUBMIT in App Store Connect — set its price schedule and localized display name/description (and optional review screenshot) via the ASC REST API. Use at Phase 6 (Pre-Release), after the IAP is built in-app (Phase
Open skill - /keyword-optimizer
Optimize app title, subtitle, and keywords for maximum App Store discoverability. Use when launching a new app, improving search rankings, entering new markets/languages, or safely optimizing ASO for an app with existing traffic.
Open skill

