Claude-code-templates swift-concurrency-expert
Review and fix Swift concurrency issues such as actor isolation and Sendable violations.
install
source · Clone the upstream repo
git clone https://github.com/davila7/claude-code-templates
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/davila7/claude-code-templates "$T" && mkdir -p ~/.claude/skills && cp -r "$T/cli-tool/components/skills/development/swift-concurrency-expert" ~/.claude/skills/davila7-claude-code-templates-swift-concurrency-expert && rm -rf "$T"
manifest:
cli-tool/components/skills/development/swift-concurrency-expert/SKILL.mdsource content
Swift Concurrency Expert
Overview
Review and fix Swift Concurrency issues in Swift 6.2+ codebases by applying actor isolation, Sendable safety, and modern concurrency patterns with minimal behavior changes.
When to Use
- When the user asks to review Swift concurrency usage or fix compiler diagnostics.
- When you need guidance on actor isolation,
,Sendable
, or async migration.@MainActor
Workflow
1. Triage the issue
- Capture the exact compiler diagnostics and the offending symbol(s).
- Check project concurrency settings: Swift language version (6.2+), strict concurrency level, and whether approachable concurrency (default actor isolation / main-actor-by-default) is enabled.
- Identify the current actor context (
,@MainActor
,actor
) and whether a default actor isolation mode is enabled.nonisolated - Confirm whether the code is UI-bound or intended to run off the main actor.
2. Apply the smallest safe fix
Prefer edits that preserve existing behavior while satisfying data-race safety.
Common fixes:
- UI-bound types: annotate the type or relevant members with
.@MainActor - Protocol conformance on main actor types: make the conformance isolated (e.g.,
).extension Foo: @MainActor SomeProtocol - Global/static state: protect with
or move into an actor.@MainActor - Background work: move expensive work into a
async function on a@concurrent
type or use annonisolated
to guard mutable state.actor - Sendable errors: prefer immutable/value types; add
conformance only when correct; avoidSendable
unless you can prove thread safety.@unchecked Sendable
3. Verify the fix
- Rebuild and confirm all concurrency diagnostics are resolved with no new warnings introduced.
- Run the test suite to check for regressions — concurrency changes can introduce subtle runtime issues even when the build is clean.
- If the fix surfaces new warnings, treat each one as a fresh triage (return to step 1) and resolve iteratively until the build is clean and tests pass.
Examples
UI-bound type — adding @MainActor
// Before: data-race warning because ViewModel is accessed from the main thread // but has no actor isolation class ViewModel: ObservableObject { @Published var title: String = "" func load() { title = "Loaded" } } // After: annotate the whole type so all stored state and methods are // automatically isolated to the main actor @MainActor class ViewModel: ObservableObject { @Published var title: String = "" func load() { title = "Loaded" } }
Protocol conformance isolation
// Before: compiler error — SomeProtocol method is nonisolated but the // conforming type is @MainActor @MainActor class Foo: SomeProtocol { func protocolMethod() { /* accesses main-actor state */ } } // After: scope the conformance to @MainActor so the requirement is // satisfied inside the correct isolation context @MainActor extension Foo: SomeProtocol { func protocolMethod() { /* safely accesses main-actor state */ } }
Background work with @concurrent
// Before: expensive computation blocks the main actor @MainActor func processData(_ input: [Int]) -> [Int] { input.map { heavyTransform($0) } // runs on main thread } // After: hop off the main actor for the heavy work, then return the result // The caller awaits the result and stays on its own actor nonisolated func processData(_ input: [Int]) async -> [Int] { await Task.detached(priority: .userInitiated) { input.map { heavyTransform($0) } }.value } // Or, using a @concurrent async function (Swift 6.2+): @concurrent func processData(_ input: [Int]) async -> [Int] { input.map { heavyTransform($0) } }
Reference material
- See
for Swift 6.2 changes, patterns, and examples.references/swift-6-2-concurrency.md - See
when the project is opted into approachable concurrency mode.references/approachable-concurrency.md - See
for SwiftUI-specific concurrency guidance.references/swiftui-concurrency-tour-wwdc.md