Skip to content
Mobile
Skill

/swift-concurrency

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,

From plugin
swift-ios-skills
1.3k86 skills1 MCP

Claude Code

$ npx -y skills add dpearson2699/swift-ios-skills --skill swift-concurrency --agent claude-code

SKILL.md

swift-concurrency.SKILL.md
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."

Swift Concurrency

Review, fix, and write concurrent Swift code targeting Swift 6.3+. Gate Swift 6.4 / Xcode 27 beta cleanup APIs behind explicit toolchain and availability checks. Apply actor isolation, Sendable safety, and modern concurrency patterns with minimal behavior changes.

Contents

  • [Triage Workflow](#triage-workflow)
  • [Swift 6.2 Language Changes](#swift-62-language-changes)
  • [Actor Isolation Rules](#actor-isolation-rules)
  • [Sendable Rules](#sendable-rules)
  • [Structured Concurrency Patterns](#structured-concurrency-patterns)
  • [Task Cancellation](#task-cancellation)
  • [Actor Reentrancy](#actor-reentrancy)
  • [AsyncSequence and AsyncStream](#asyncsequence-and-asyncstream)
  • [`@Observable and Concurrency`](#observable-and-concurrency)
  • [Synchronization Primitives](#synchronization-primitives)
  • [Common Mistakes](#common-mistakes)
  • [Review Checklist](#review-checklist)
  • [References](#references)

Triage Workflow

When diagnosing a concurrency issue, follow this sequence:

Step 1: Capture context

  • Copy the exact compiler diagnostic(s) and the offending symbol(s).
  • Identify the project's concurrency settings:
  • Swift language version (must be 6.2+).
  • Xcode/toolchain version for version-specific features and release-note

workarounds.

  • Whether Approachable Concurrency is enabled.
  • Whether Default Actor Isolation is set to `MainActor`.
  • Swift 6 strict concurrency status: complete/errors in Swift 6 language mode;

Complete / Targeted / Minimal only when auditing Swift 5 migration settings.

  • Determine the current actor context of the code (`@MainActor`, custom `actor`,

`nonisolated`) and whether a default isolation mode is active.

  • Confirm whether the code is UI-bound or intended to run off the main actor.

Step 2: Apply the smallest safe fix

Prefer edits that preserve existing behavior while satisfying data-race safety.

| Situation | Recommended fix | |---|---| | UI-bound type | Annotate the type or relevant members with `@MainActor`. | | Protocol conformance on MainActor type | Use an isolated conformance: `extension Foo: @MainActor Proto`. | | Global / static state | Protect with `@MainActor` or move into an actor. | | Background work needed | Use a `@concurrent` async function on a `nonisolated` type. | | Sendable error | Prefer immutable value types. Add `Sendable` only when correct. | | Cross-isolation callback | Use `sending` parameters (SE-0430) for finer control. |

Step 3: Verify

  • Rebuild and confirm the diagnostic is resolved.
  • Check for new warnings introduced by the fix.
  • Ensure no unnecessary `@unchecked Sendable` or `nonisolated(unsafe)` was added.
  • For build-setting reviews, stop at settings plus the smallest code-level

remediation. Do not add Thread Sanitizer, broad migration ordering, or architecture advice unless the prompt asks for diagnostics or migration.

Swift 6.2 Language Changes

Swift 6.2 introduces "approachable concurrency" -- a set of language changes that make concurrent code safer by default while reducing annotation burden. In Xcode, Approachable Concurrency and Default Actor Isolation are separate build settings: use Approachable Concurrency for the bundled upcoming-feature flags, and set Default Actor Isolation to `MainActor` when you want unannotated code inferred as `@MainActor`.

SE-0466: Default MainActor Isolation

With the `-default-isolation MainActor` compiler flag, SwiftPM `.defaultIsolation(MainActor.self)`, or Xcode's `Default Actor Isolation` setting set to `MainActor`, unannotated declarations in the module are inferred as `@MainActor` unless explicitly opted out.

**Effect:** Eliminates most data-race safety errors for UI-bound code and global/static state without writing `@MainActor` everywhere.

// With default MainActor isolation enabled, these are implicitly @MainActor:
final class StickerLibrary {
    static let shared = StickerLibrary()  // safe -- on MainActor
    var stickers: [Sticker] = []
}

final class StickerModel {
    let photoProcessor = PhotoProcessor()
    var selection: [PhotosPickerItem] = []
}

// Conformances are also implicitly isolated:
extension StickerModel: Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

**When to use:** Recommended for apps, scripts, and other executable targets where most code is UI-bound. Not recommended for library targets that should remain actor-agnostic.

SE-0461: nonisolated(nonsending)

Nonisolated async functions now stay on the caller's actor by default instead of hopping to the global concurrent executor. This is the `nonisolated(nonsending)` behavior.

class PhotoProcessor {
    func extractSticker(data: Data, with id: String?) async -> Sticker? {
        // In Swift 6.2+, this runs on the caller's actor (e.g., MainActor)
        // instead of hopping to a background thread.
        // ...
    }
}

@MainActor
final class StickerModel {
    let photoProcessor = PhotoProcessor()

    func extractSticker(_ item: PhotosPickerItem) async throws -> Sticker? {
        guard let data = try await item.loadTransferable(type: Data.self) else {
            return nil
        }
        // No data race -- photoProcessor stays on MainActor
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Use `@concurrent` to explicitly request background execution when needed.

##

Read more
@dpearson2699
Ships withswift-ios-skills

86 agent skills optimized for iOS 26+ development with Swift 6.3 and modern Apple frameworks.

1.3k86 skills1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
1.3k
Star history of dpearson2699/swift-ios-skills on GitHub, a chart by star-history.com

Other skills on swift-ios-skills.

alarmkit

alarmkit

Implement AlarmKit alarms and countdown timers for iOS and iPadOS with Lock Screen, Dynamic Island, StandBy, and paired Apple…

app-clips

app-clips

Build iOS App Clips with invocation URLs, App Clip Codes, NFC, QR codes, Safari banners, Maps, Messages, target setup, App Store…

More skills from other plugins.

deep-code-review

deep-code-review

In-depth design-focused code review - understands codebase context before evaluating PR changes, posts structured feedback to…

expo1d53k
@expo@expoInstall Skill
modlens

modlens

Plug-in vision for text-only models. Hard rule: when a file path or URL with an image extension (.png, .jpg, .jpeg, .webp, .gif,…

modlens2w4.6k
@liustack@liustackInstall Skill
appllama-app-design-skill

appllama-app-design-sk…

Build native-feeling, benchmark-quality mobile app screens (Expo / React Native). Use when designing or implementing any mobile…

appllama2mo3.9k
@appllama@appllamaInstall Skill

Questions about swift-concurrency.

Which coding agents can use swift-concurrency?
swift-concurrency installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.