Skip to content
Skillpedia
APIs & servers (backend)280k · #125

swift-concurrency-6-2

Helps your agent use Swift 6.2's new concurrency features. It allows background tasks to be run in an organized and safe way.

What it does

This tool helps you use Swift 6.2's new concurrency features. It makes code safer by preventing common errors when multiple parts of the program try to access the same information simultaneously, especially for background tasks.

When to use it

  • ✓When migrating your Swift code to version 6.2.
  • ✓When the compiler reports 'data race' errors (unsafe data access).
  • ✓To organize tasks that need to run in the background without freezing the main program.

Example of what to ask your AI

“How can I safely run a time-consuming task in the background in Swift 6.2?”

Want more? Open the sections below.

How to use

The easiest way: copy the message below and paste it into Claude, ChatGPT, Cursor or any AI. It reads the skill and follows the instructions.

Skill link

https://github.com/affaan-m/ECC/blob/main/pi/core/skills/swift-concurrency-6-2/SKILL.md

Ready-to-paste message

Use this skill to help me: https://github.com/affaan-m/ECC/blob/main/pi/core/skills/swift-concurrency-6-2/SKILL.md Read the SKILL.md file at that link and follow its instructions for my task.
How it works

Swift 6.2 changes the default behavior so code continues running where it was called, unless you explicitly use `@concurrent`. This prevents different code parts from unintentionally modifying data at the same time.

Installation

Easiest way: copy the skill link and paste it into Claude, ChatGPT or Cursor asking it to follow the instructions.

In the terminal (Claude Code, Codex, Cursor), in your project folder:

npx skills add affaan-m/ECC --skill swift-concurrency-6-2

Or download just the file:

curl -L https://raw.githubusercontent.com/affaan-m/ECC/main/pi/core/skills/swift-concurrency-6-2/SKILL.md -o SKILL.md
Technical content (original SKILL.md)

Original text by the author, straight from GitHub.

Swift 6.2 Approachable Concurrency

Patterns for adopting Swift 6.2's concurrency model where code runs single-threaded by default and concurrency is introduced explicitly. Eliminates common data-race errors without sacrificing performance.

When to Activate

  • Migrating Swift 5.x or 6.0/6.1 projects to Swift 6.2
  • Resolving data-race safety compiler errors
  • Designing MainActor-based app architecture
  • Offloading CPU-intensive work to background threads
  • Implementing protocol conformances on MainActor-isolated types
  • Enabling Approachable Concurrency build settings in Xcode 26

Core Problem: Implicit Background Offloading

In Swift 6.1 and earlier, async functions could be implicitly offloaded to background threads, causing data-race errors even in seemingly safe code:

// Swift 6.1: ERROR
@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 }

        // Error: Sending 'self.photoProcessor' risks causing data races
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Swift 6.2 fixes this: async functions stay on the calling actor by default.

// Swift 6.2: OK — async stays on MainActor, no data race
@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 }
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Core Pattern — Isolated Conformances

MainActor types can now conform to non-isolated protocols safely:

protocol Exportable {
    func export()
}

// Swift 6.1: ERROR — crosses into main actor-isolated code
// Swift 6.2: OK with isolated conformance
extension StickerModel: @MainActor Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

The compiler ensures the conformance is only used on the main actor:

// OK — ImageExporter is also @MainActor
@MainActor
struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Safe: same actor isolation
    }
}

// ERROR — nonisolated context can't use MainActor conformance
nonisolated struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Error: Main actor-isolated conformance cannot be used here
    }
}

Core Pattern — Global and Static Variables

Protect global/static state with MainActor:

// Swift 6.1: ERROR — non-Sendable type may have shared mutable state
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Error
}

// Fix: Annotate with @MainActor
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // OK
}

MainActor Default Inference Mode

Swift 6.2 introduces a mode where MainActor is inferred by default — no manual annotations needed:

// With MainActor default inference enabled:
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Implicitly @MainActor
}

final class StickerModel {
    let photoProcessor: PhotoProcessor
    var selection: [PhotosPickerItem]  // Implicitly @MainActor
}

extension StickerModel: Exportable {  // Implicitly @MainActor conformance
    func export() {
        photoProcessor.exportAsPNG()
    }
}

This mode is opt-in and recommended for apps, scripts, and other executable targets.

Core Pattern — @concurrent for Background Work

When you need actual parallelism, explicitly offload with @concurrent:

Important: This example requires Approachable Concurrency build settings — SE-0466 (MainActor default isolation) and SE-0461 (NonisolatedNonsendingByDefault). With these enabled, extractSticker stays on the caller's actor, making mutable state access safe. Without these settings, this code has a data race — the compiler will flag it.

nonisolated final class PhotoProcessor {
    private var cachedStickers: [String: Sticker] = [:]

    func extractSticker(data: Data, with id: String) async -> Sticker {
        if let sticker = cachedStickers[id] {
            return sticker

…
FAQ

What is a 'data race'?

It's an error that occurs when two or more parts of your program try to read and write the same data simultaneously, leading to unpredictable results or crashes.

What does 'single-threaded by default' mean?

It means that, by default, code runs on a single thread of execution, like a queue. This makes it easier to avoid 'data race' errors because only one thing happens at a time.

What is `@concurrent`?

It's a special instruction you use to tell Swift that a specific function should run in the background, on a different thread, so it doesn't interfere with the program's main flow.

Details

Original description by the author

Swift 6.2 Approachable Concurrency — single-threaded by default, @concurrent for explicit background offloading, isolated conformances for main actor types. Use when adopting Swift 6.2 concurrency — offloading with @concurrent or resolving main-actor isolation.

repo: affaan-m/ECC

Popularity

GitHub stars
280k
Ranking position
#125
License
MIT
Updated
10/15/2026

Is this skill useful?

0

Sign in to vote.

Comments

  • …

More skills from this repository

Similar skills