Communitygithub.com

swift-concurrency-6-2

Concurrencia Aproximable de Swift 6.2: un único hilo por defecto, @concurrent para descarga explícita en segundo plano, conformidades aisladas para tipos del actor principal. Úsalo al adoptar la concurrencia de Swift 6.2: descarga con @concurrent o resuelve el aislamiento del actor principal.

¿Qué es swift-concurrency-6-2?

Esta habilidad proporciona pautas y patrones para adoptar el modelo de concurrencia de Swift 6.2, donde el código se ejecuta en un solo hilo por defecto y la concurrencia se introduce explícitamente. El objetivo principal es eliminar los errores comunes de carrera de datos sin sacrificar el rendimiento, ofreciendo una migración no disruptiva desde versiones anteriores de Swift. La habilidad cubre varios patrones clave: conformidades aisladas, que permiten que los tipos del actor principal cumplan con protocolos no aislados de forma segura; variables globales y estáticas protegidas con MainActor; y el uso del atributo `@concurrent` para descargar trabajo intensivo de CPU a hilos de fondo. También introduce el modo de inferencia predeterminada de MainActor, que reduce la necesidad de anotaciones manuales. Los desarrolladores pueden activar esta habilidad al migrar proyectos a Swift 6.2, resolver errores de seguridad contra carreras de datos, diseñar arquitecturas centradas en MainActor o descargar tareas pesadas. La habilidad ofrece una guía paso a paso para la migración, mejores prácticas y antipatrones a evitar, todo ello con el objetivo de hacer que la concurrencia sea más segura y fácil de usar.

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

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

Concurrencia Aproximable de Swift 6.2

Patrones para adoptar el modelo de concurrencia de Swift 6.2, donde el código se ejecuta en un solo hilo por defecto y la concurrencia se introduce explícitamente. Elimina los errores comunes de carrera de datos sin sacrificar el rendimiento.

Cuándo activarlo

  • Migrar proyectos de Swift 5.x o 6.0/6.1 a Swift 6.2
  • Resolver errores del compilador sobre seguridad contra carreras de datos
  • Diseñar arquitecturas de aplicaciones basadas en MainActor
  • Descargar trabajo intensivo de CPU a hilos de fondo
  • Implementar conformidades de protocolo en tipos aislados por MainActor
  • Habilitar los ajustes de compilación de Concurrencia Aproximable en Xcode 26

Problema central: descarga implícita a segundo plano

En Swift 6.1 y versiones anteriores, las funciones asíncronas podían descargarse implícitamente a hilos de fondo, causando errores de carrera de datos incluso en código aparentemente seguro:

// 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: Enviar 'self.photoProcessor' corre el riesgo de causar carreras de datos
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Swift 6.2 soluciona esto: las funciones asíncronas permanecen en el actor que las llama por defecto.

// Swift 6.2: OK — async permanece en MainActor, sin carrera de datos
@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)
    }
}

Patrón central: conformidades aisladas

Los tipos de MainActor ahora pueden cumplir con protocolos no aislados de forma segura:

protocol Exportable {
    func export()
}

// Swift 6.1: ERROR — cruza al código aislado por el actor principal
// Swift 6.2: OK con conformidad aislada
extension StickerModel: @MainActor Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

El compilador asegura que la conformidad solo se use en el actor principal:

// OK — ImageExporter también es @MainActor
@MainActor
struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Seguro: mismo aislamiento de actor
    }
}

// ERROR — un contexto no aislado no puede usar la conformidad de MainActor
nonisolated struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // Error: la conformidad aislada por el actor principal no se puede usar aquí
    }
}

Patrón central: variables globales y estáticas

Protege el estado global/estático con MainActor:

// Swift 6.1: ERROR — el tipo no Sendable puede tener estado mutable compartido
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Error
}

// Solución: Anotar con @MainActor
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // OK
}

Modo de inferencia predeterminada de MainActor

Swift 6.2 introduce un modo en el que MainActor se infiere por defecto, sin necesidad de anotaciones manuales:

// Con la inferencia predeterminada de MainActor habilitada:
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // Implícitamente @MainActor
}

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

extension StickerModel: Exportable {  // Conformidad implícitamente @MainActor
    func export() {
        photoProcessor.exportAsPNG()
    }
}

Este modo es opcional y se recomienda para aplicaciones, scripts y otros objetivos ejecutables.

Patrón central: @concurrent para trabajo en segundo plano

Cuando necesitas paralelismo real, descarga explícitamente con @concurrent:

Importante: Este ejemplo requiere los ajustes de compilación de Concurrencia Aproximable: SE-0466 (aislamiento predeterminado de MainActor) y SE-0461 (NonisolatedNonsendingByDefault). Con estos habilitados, extractSticker permanece en el actor de quien llama, haciendo seguro el acceso al estado mutable. Sin estos ajustes, este código tiene una carrera de datos: el compilador la marcará.

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
    }

    // Descarga trabajo costoso al grupo de hilos concurrentes
    @concurrent
    static func extractSubject(from data: Data) async -> Sticker { /* ... */ }
}

// Quienes llaman deben usar await
let processor = PhotoProcessor()
processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id)

Para usar @concurrent:

  1. Marca el tipo contenedor como nonisolated
  2. Agrega @concurrent a la función
  3. Agrega async si aún no es asíncrona
  4. Agrega await en los sitios de llamada

Decisiones clave de diseño

DecisiónJustificación
Un solo hilo por defectoEl código más natural está libre de carreras de datos; la concurrencia es opcional
Async permanece en el actor que llamaElimina la descarga implícita que causaba errores de carrera de datos
Conformidades aisladasLos tipos de MainActor pueden cumplir con protocolos sin soluciones inseguras
@concurrent explícito y optativoLa ejecución en segundo plano es una decisión de rendimiento deliberada, no accidental
Inferencia predeterminada de MainActorReduce la necesidad de anotaciones @MainActor para objetivos de aplicación
Adopción optativaRuta de migración no disruptiva: habilita las características de forma incremental

Pasos de migración

  1. Habilitar en Xcode: Compilador Swift > sección de Concurrencia en los ajustes de compilación
  2. Habilitar en SPM: Usa la API SwiftSettings en el manifiesto del paquete
  3. Usar las herramientas de migración: Cambios automáticos de código vía swift.org/migration
  4. Empezar con valores predeterminados de MainActor: Habilita el modo de inferencia para objetivos de aplicación
  5. Agregar @concurrent donde sea necesario: Perfila primero, luego descarga las rutas calientes
  6. Probar a fondo: Los problemas de carrera de datos se convierten en errores en tiempo de compilación

Mejores prácticas

  • Empieza en MainActor — escribe código de un solo hilo primero, optimiza después
  • Usa @concurrent solo para trabajo intensivo de CPU — procesamiento de imágenes, compresión, cálculos complejos
  • Habilita el modo de inferencia de MainActor para objetivos de aplicación que son principalmente de un solo hilo
  • Perfila antes de descargar — usa Instruments para encontrar cuellos de botella reales
  • Protege los globales con MainActor — el estado mutable global/estático necesita aislamiento del actor
  • Usa conformidades aisladas en lugar de soluciones nonisolated o envoltorios @Sendable
  • Migra de forma incremental — habilita las características una a una en los ajustes de compilación

Antipatrones a evitar

  • Aplicar @concurrent a cada función asíncrona (la mayoría no necesita ejecución en segundo plano)
  • Usar nonisolated para suprimir errores del compilador sin entender el aislamiento
  • Mantener patrones legacy DispatchQueue cuando los actores proporcionan la misma seguridad
  • Omitir las comprobaciones de model.availability en código de Foundation Models relacionado con concurrencia
  • Pelear contra el compilador — si informa de una carrera de datos, el código tiene un problema de concurrencia real
  • Asumir que todo el código asíncrono se ejecuta en segundo plano (Swift 6.2 por defecto: permanece en el actor que llama)

Cuándo usarlo

  • Todos los proyectos nuevos con Swift 6.2+ (Concurrencia Aproximable es la opción predeterminada recomendada)
  • Migrar aplicaciones existentes desde Swift 5.x o 6.0/6.1 con concurrencia
  • Resolver errores del compilador sobre seguridad contra carreras de datos durante la adopción de Xcode 26
  • Construir arquitecturas de aplicaciones centradas en MainActor (la mayoría de las aplicaciones de interfaz de usuario)
  • Optimización de rendimiento: descargar cálculos pesados específicos a segundo plano

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 relacionados