Communitygithub.com

swift-concurrency-6-2

Concurrence accessible Swift 6.2 — monofilaire par défaut, @concurrent pour un déchargement explicite en arrière-plan, conformances isolées pour les types MainActor. À utiliser lors de l'adoption de la concurrence Swift 6.2 — déchargement avec @concurrent ou résolution de l'isolation MainActor.

Qu'est-ce que swift-concurrency-6-2 ?

Ce guide décrit le modèle de concurrence « Approachable Concurrency » introduit avec Swift 6.2, où l'exécution est par défaut monofilaire (single-threaded) et la concurrence est explicitement opt-in. Il remplace les mécanismes antérieurs (Swift 5.x, 6.0, 6.1) qui pouvaient provoquer des déchargements implicites vers des threads d'arrière-plan, source de course aux données (data races) difficiles à détecter. Le résumé détaille les trois piliers : (1) l'isolation par défaut (les fonctions `async` restent sur l'acteur appelant), (2) les conformances isolées (un type `@MainActor` peut adopter un protocole non isolé de manière sécurisée), (3) les variables globales et statiques protégées par `@MainActor` avec inférence automatique. L'annotation `@concurrent` permet d'activer explicitement le parallélisme pour les tâches coûteuses. Le guide explique la migration depuis Swift 5.x/6.0, les nouvelles options de Build Settings (SE-0466, SE-0461), et présente des anti-patrons clés. Il est destiné aux développeurs utilisant Xcode 26, que ce soit pour une application MainActor ou un package SPM, et fournit des étapes de migration incrémentales pour adopter le modèle sans régressions.

Compatible avec~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/affaan-m/ECC/tree/main/skills/swift-concurrency-6-2

Demander à votre IA préférée

Ouvre une nouvelle conversation avec cette compétence d'agent déjà préchargée.

Documentation

Concurrence accessible Swift 6.2

Modèles pour adopter le modèle de concurrence de Swift 6.2, où le code s'exécute par défaut sur un seul thread et où la concurrence est introduite explicitement. Élimine les erreurs classiques de course aux données sans sacrifier les performances.

Quand l'activer

  • Migration de projets Swift 5.x ou 6.0/6.1 vers Swift 6.2
  • Résolution d'erreurs de sécurité liées aux courses aux données lors de la compilation
  • Conception d'architecture d'application basée sur MainActor
  • Déchargement de travaux intensifs vers des threads d'arrière-plan
  • Implémentation de conformances de protocole sur des types isolés par MainActor
  • Activation des paramètres de build « Approachable Concurrency » dans Xcode 26

Problème fondamental : déchargement implicite en arrière-plan

Dans Swift 6.1 et antérieur, les fonctions async pouvaient être implicitement déchargées vers des threads d'arrière-plan, provoquant des erreurs de course aux données même dans du code apparemment sûr :

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

        // Erreur : l'envoi de 'self.photoProcessor' risque de provoquer des courses aux données
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Swift 6.2 corrige cela : les fonctions async restent par défaut sur l'acteur appelant.

// Swift 6.2 : OK — async reste sur MainActor, pas de course aux données
@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)
    }
}

Modèle fondamental — Conformances isolées

Les types MainActor peuvent désormais adopter des protocoles non isolés en toute sécurité :

protocol Exportable {
    func export()
}

// Swift 6.1 : ERREUR — traverse du code isolé par MainActor
// Swift 6.2 : OK avec la conformance isolée
extension StickerModel: @MainActor Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

Le compilateur garantit que la conformance n'est utilisée que sur l'acteur principal :

// OK — ImageExporter est également @MainActor
@MainActor
struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Sûr : même isolement d'acteur
    }
}

// ERREUR — un contexte non isolé ne peut pas utiliser la conformance MainActor
nonisolated struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Erreur : la conformance isolée par MainActor ne peut pas être utilisée ici
    }
}

Modèle fondamental — Variables globales et statiques

Protégez l'état global/statique avec MainActor :

// Swift 6.1 : ERREUR — le type non Sendable peut avoir un état mutable partagé
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Erreur
}

// Correction : annoter avec @MainActor
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // OK
}

Mode d'inférence par défaut de MainActor

Swift 6.2 introduit un mode où MainActor est inféré par défaut — aucune annotation manuelle nécessaire :

// Avec l'inférence par défaut de MainActor activée :
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Implicitement @MainActor
}

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

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

Ce mode est optionnel (opt-in) et recommandé pour les applications, scripts et autres cibles exécutables.

Modèle fondamental — @concurrent pour le travail en arrière-plan

Lorsque vous avez besoin de parallélisme réel, déchargez explicitement avec @concurrent :

Important : Cet exemple nécessite les paramètres de build Approachable Concurrency — SE-0466 (isolation par défaut de MainActor) et SE-0461 (NonisolatedNonsendingByDefault). Avec ceux-ci activés, extractSticker reste sur l'acteur appelant, rendant l'accès à l'état mutable sûr. Sans ces paramètres, ce code présente une course aux données — le compilateur le signalera.

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
        }

        let sticker = await Self.extractSubject(from: data)
        cachedStickers[id] = sticker
        return sticker
    }

    // Décharger le travail coûteux vers le pool de threads concurrents
    @concurrent
    static func extractSubject(from data: Data) async -> Sticker { /* ... */ }
}

// Les appelants doivent utiliser await
let processor = PhotoProcessor()
processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id)

Pour utiliser @concurrent :

  1. Marquez le type contenant comme nonisolated
  2. Ajoutez @concurrent à la fonction
  3. Ajoutez async si elle n'est pas déjà asynchrone
  4. Ajoutez await aux sites d'appel

Décisions de conception clés

DécisionJustification
Monofilaire par défautLe code le plus naturel est exempt de courses aux données ; la concurrence est opt-in
Async reste sur l'acteur appelantÉlimine le déchargement implicite qui causait des erreurs de courses aux données
Conformances isoléesLes types MainActor peuvent adopter des protocoles sans contournements dangereux
@concurrent explicite (opt-in)L'exécution en arrière-plan est un choix délibéré de performance, pas accidentel
Inférence par défaut de MainActorRéduit les annotations @MainActor répétitives pour les cibles d'application
Adoption optionnelleChemin de migration non cassant — activez les fonctionnalités de manière incrémentale

Étapes de migration

  1. Activer dans Xcode : Compilateur Swift > section Concurrency dans les Paramètres de build
  2. Activer dans SPM : Utilisez l'API SwiftSettings dans le manifeste du paquet
  3. Utiliser les outils de migration : Modifications de code automatiques via swift.org/migration
  4. Commencer par les valeurs par défaut de MainActor : Activez le mode d'inférence pour les cibles d'application
  5. Ajouter @concurrent là où nécessaire : Analysez d'abord, puis déchargez les chemins chauds
  6. Tester en profondeur : Les problèmes de course aux données deviennent des erreurs de compilation

Bonnes pratiques

  • Commencez sur MainActor — écrivez du code monofilaire d'abord, optimisez ensuite
  • Utilisez @concurrent uniquement pour le travail intensif en CPU — traitement d'images, compression, calculs complexes
  • Activez le mode d'inférence de MainActor pour les cibles d'application principalement monofilaires
  • Analysez avant de décharger — utilisez Instruments pour trouver les véritables goulots d'étranglement
  • Protégez les variables globales avec MainActor — l'état mutable global/statique nécessite un isolement par acteur
  • Utilisez les conformances isolées au lieu de contournements nonisolated ou de wrappers @Sendable
  • Migrez de manière incrémentale — activez les fonctionnalités une par une dans les paramètres de build

Anti-patrons à éviter

  • Appliquer @concurrent à chaque fonction async (la plupart n'ont pas besoin d'exécution en arrière-plan)
  • Utiliser nonisolated pour supprimer des erreurs du compilateur sans comprendre l'isolement
  • Conserver les motifs DispatchQueue hérités alors que les acteurs offrent la même sécurité
  • Ignorer les vérifications model.availability dans le code Foundation Models lié à la concurrence
  • Lutter contre le compilateur — s'il signale une course aux données, le code a un vrai problème de concurrence
  • Supposer que tout code asynchrone s'exécute en arrière-plan (Swift 6.2 par défaut : reste sur l'acteur appelant)

Quand utiliser

  • Tous les nouveaux projets Swift 6.2+ (Approachable Concurrency est le mode par défaut recommandé)
  • Migration d'applications existantes depuis Swift 5.x ou 6.0/6.1
  • Résolution d'erreurs de sécurité liées aux courses aux données lors de l'adoption de Xcode 26
  • Construction d'architectures d'applications centrées sur MainActor (la plupart des applications d'interface utilisateur)
  • Optimisation des performances — déchargement de calculs lourds spécifiques en arrière-plan

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

accessibility

Design, implement, and audit inclusive digital products using WCAG 2.2 Level AA. Use when building or auditing UI that must meet WCAG 2.2 Level AA, or when reviewing a change for keyboard, contrast, or screen-reader support.

affaan-m/content-engine

Create platform-native content systems for X, LinkedIn, TikTok, YouTube, newsletters, and repurposed multi-platform campaigns. Use when the user wants social posts, threads, scripts, content calendars, or one source asset adapted cleanly across platforms.

affaan-m/ECC

Multi-platform content distribution across X, LinkedIn, Threads, and Bluesky. Adapts content per platform using content-engine patterns. Never posts identical content cross-platform. Use when the user wants to distribute content across social platforms.

affaan-m/fal-ai-media

Unified media generation via fal.ai MCP — image, video, and audio. Covers text-to-image (Nano Banana), text/image-to-video (Seedance, Kling, Veo 3), text-to-speech (CSM-1B), and video-to-audio (ThinkSound). Use when the user wants to generate images, videos, or audio with AI.

affaan-m/manim-video

日本語翻訳:このファイルは manim-video 用の日本語翻訳が必要です

affaan-m/remotion-video-creation

Remotion のベストプラクティス - React で動画を作成する。3D、アニメーション、音声、字幕、チャート、トランジションなどをカバーするドメイン固有の29のルール。

affaan-m/video-editing

AI-assisted video editing workflows for cutting, structuring, and augmenting real footage. Covers the full pipeline from raw capture through FFmpeg, Remotion, ElevenLabs, fal.ai, and final polish in Descript or CapCut. Use when the user wants to edit video, cut footage, create vlogs, or build video content.

agent-architecture-audit

Full-stack diagnostic for agent and LLM applications. Audits the 12-layer agent stack for wrapper regression, memory pollution, tool discipline failures, hidden repair loops, and rendering corruption. Produces severity-ranked findings with code-first fixes. Essential for developers building agent applications, autonomous loops, or any LLM-powered feature. Use when an agent or LLM feature misbehaves and the failing layer is unknown, or before shipping an agent stack.

agent-eval

Head-to-head comparison of coding agents (Claude Code, Aider, Codex, etc.) on custom tasks with pass rate, cost, time, and consistency metrics. Use when choosing between coding agents, or when a change to an agent setup needs measured pass rate, cost, and time rather than an impression.

agent-harness-construction

Design and optimize AI agent action spaces, tool definitions, and observation formatting for higher completion rates. Use when defining or revising an agent

agentic-engineering

Operate as an agentic engineer using eval-first execution, decomposition, and cost-aware model routing. Use when planning or executing engineering work that agents will carry out end to end.

agentic-os

Build persistent multi-agent operating systems on Claude Code. Covers kernel architecture, specialist agents, slash commands, file-based memory, scheduled automation, and state management without external databases. Use when building a persistent multi-agent system on Claude Code with its own memory, commands, and scheduling.

agent-introspection-debugging

Structured self-debugging workflow for AI agent failures using capture, diagnosis, contained recovery, and introspection reports. Use when an agent run fails and you need a reproducible diagnosis instead of a retry.

agent-payment-x402

Add x402 payment execution to AI agents with per-task budgets, spending controls, and non-custodial wallets. Supports Base through agentwallet-sdk and X Layer through OKX Payments / OKX Agent Payments Protocol. Use when an agent must pay for something itself and needs per-task budgets, spending controls, and a non-custodial wallet.

agent-self-evaluation

Use after completing any non-trivial task. The agent self-rates its output on 5 axes — accuracy, completeness, clarity, actionability, conciseness — with concrete evidence per criterion. Produces a structured 1-5 scorecard with specific improvement suggestions.

agent-sort

Build an evidence-backed ECC install plan for a specific repo by sorting skills, commands, rules, hooks, and extras into DAILY vs LIBRARY buckets using parallel repo-aware review passes. Use when ECC should be trimmed to what a project actually needs instead of loading the full bundle.

ai-first-engineering

Engineering operating model for teams where AI agents generate a large share of implementation output. Use when setting team process, review gates, or ownership rules for a codebase largely written by agents.

ai-regression-testing

Regression testing strategies for AI-assisted development. Sandbox-mode API testing without database dependencies, automated bug-check workflows, and patterns to catch AI blind spots where the same model writes and reviews code. Use when adding regression coverage to AI-assisted code, or when the same model both wrote and reviewed a change.

android-clean-architecture

Clean Architecture patterns for Android and Kotlin Multiplatform projects — module structure, dependency rules, UseCases, Repositories, and data layer patterns. Use when structuring modules, layers, or data flow in an Android or KMP project.

angular-developer

Generates Angular code and provides architectural guidance. Trigger when creating projects, components, or services, or for best practices on reactivity (signals, linkedSignal, resource), forms, dependency injection, routing, SSR, accessibility (ARIA), animations, styling (component styles, Tailwind CSS), testing, or CLI tooling.

Skills associés