Communitygithub.com

swift-concurrency-6-2

Swift 6.2 접근 가능한 동시성 — 기본 단일 스레드, 명시적 백그라운드 오프로드를 위한 @concurrent, 메인 액터 타입을 위한 격리된 준수. Swift 6.2 동시성 채택 시 @concurrent로 오프로드하거나 메인 액터 격리 해결에 사용합니다.

swift-concurrency-6-2란 무엇인가요?

이 스킬은 Swift 6.2의 접근 가능한 동시성 모델을 채택하기 위한 패턴을 제공합니다. 기본적으로 코드가 단일 스레드로 실행되고 동시성이 명시적으로 도입되는 이 모델은 일반적인 데이터 경합 오류를 성능 저하 없이 제거합니다. 주요 대상은 Swift 5.x 또는 6.0/6.1 프로젝트를 Swift 6.2로 마이그레이션하는 개발자, 데이터 경합 안전성 컴파일러 오류를 해결하는 개발자, MainActor 기반 앱 아키텍처를 설계하는 개발자입니다. 이 스킬은 핵심 패턴으로 격리된 준수(isolated conformances), 전역/정적 변수 보호, @concurrent를 통한 명시적 백그라운드 작업 오프로드를 다룹니다. 또한 MainActor 기본 추론 모드, 마이그레이션 단계, 모범 사례 및 피해야 할 안티 패턴을 포함합니다. 지원되는 플랫폼은 Xcode 26 이상을 사용하는 Swift 6.2 프로젝트이며, Swift Package Manager(SPM)에서도 설정할 수 있습니다.

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

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

Swift 6.2 접근 가능한 동시성

코드가 기본적으로 단일 스레드로 실행되고 동시성이 명시적으로 도입되는 Swift 6.2 동시성 모델을 채택하기 위한 패턴입니다. 성능 저하 없이 일반적인 데이터 경합 오류를 제거합니다.

활성화 시점

  • Swift 5.x 또는 6.0/6.1 프로젝트를 Swift 6.2로 마이그레이션할 때
  • 데이터 경합 안전성 컴파일러 오류를 해결할 때
  • MainActor 기반 앱 아키텍처를 설계할 때
  • CPU 집약적 작업을 백그라운드 스레드로 오프로드할 때
  • MainActor 격리 타입에 프로토콜 준수를 구현할 때
  • Xcode 26에서 접근 가능한 동시성 빌드 설정을 활성화할 때

핵심 문제: 암시적 백그라운드 오프로드

Swift 6.1 및 이전 버전에서는 async 함수가 암시적으로 백그라운드 스레드로 오프로드될 수 있어 겉보기에 안전한 코드에서도 데이터 경합 오류가 발생했습니다:

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

        // 오류: 'self.photoProcessor'를 전송하면 데이터 경합이 발생할 위험이 있습니다
        return await photoProcessor.extractSticker(data: data, with: item.itemIdentifier)
    }
}

Swift 6.2에서는 이 문제가 수정되었습니다. async 함수는 기본적으로 호출한 액터에 유지됩니다.

// Swift 6.2: OK — async가 MainActor에 유지되며 데이터 경합 없음
@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)
    }
}

핵심 패턴 — 격리된 준수

MainActor 타입은 이제 비격리 프로토콜에 안전하게 준수할 수 있습니다:

protocol Exportable {
    func export()
}

// Swift 6.1: 오류 — 메인 액터 격리 코드로 넘어갑니다
// Swift 6.2: 격리된 준수로 OK
@MainActor extension StickerModel: Exportable {
    func export() {
        photoProcessor.exportAsPNG()
    }
}

컴파일러는 준수가 메인 액터에서만 사용되도록 보장합니다:

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

    mutating func add(_ item: StickerModel) {
        items.append(item)  // 안전: 동일한 액터 격리
    }
}

// 오류 — 비격리 컨텍스트는 MainActor 준수를 사용할 수 없음
nonisolated struct ImageExporter {
    var items: [any Exportable]

    mutating func add(_ item: StickerModel) {
        items.append(item)  // 오류: MainActor 격리 준수를 여기서 사용할 수 없음
    }
}

핵심 패턴 — 전역 및 정적 변수

MainActor로 전역/정적 상태를 보호하세요:

// Swift 6.1: 오류 — Sendable이 아닌 타입이 공유 가능한 변경 상태를 가질 수 있음
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // 오류
}

// 해결 방법: @MainActor로 주석 추가
@MainActor
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // OK
}

MainActor 기본 추론 모드

Swift 6.2는 MainActor가 기본적으로 추론되는 모드를 도입합니다. 수동 주석이 필요하지 않습니다:

// MainActor 기본 추론 활성화 시:
final class StickerLibrary {
    static let shared: StickerLibrary = .init()  // 암시적으로 @MainActor
}

final class StickerModel {
    let photoProcessor: PhotoProcessor
    var selection: [PhotosPickerItem]  // 암시적으로 @MainActor
}

@MainActor extension StickerModel: Exportable {  // 암시적으로 @MainActor 준수
    func export() {
        photoProcessor.exportAsPNG()
    }
}

이 모드는 옵트인 방식이며 앱, 스크립트 및 기타 실행 가능 타겟에 권장됩니다.

핵심 패턴 — 백그라운드 작업을 위한 @concurrent

실제 병렬 처리가 필요할 때는 @concurrent로 명시적으로 오프로드하세요:

중요: 이 예제는 접근 가능한 동시성 빌드 설정(SE-0466 MainActor 기본 격리 및 SE-0461 NonisolatedNonsendingByDefault)이 필요합니다. 이 설정이 활성화되면 extractSticker는 호출자의 액터에 유지되어 변경 가능한 상태 접근이 안전해집니다. 이 설정이 없으면 이 코드에 데이터 경합이 있습니다 — 컴파일러가 이를 플래그합니다.

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
    }

    // 비용이 많이 드는 작업을 동시 스레드 풀로 오프로드
    @concurrent
    static func extractSubject(from data: Data) async -> Sticker { /* ... */ }
}

// 호출자는 await 해야 함
let processor = PhotoProcessor()
processedPhotos[item.id] = await processor.extractSticker(data: data, with: item.id)

@concurrent를 사용하려면:

  1. 포함하는 타입을 nonisolated로 표시
  2. 함수에 @concurrent 추가
  3. 아직 비동기가 아니면 async 추가
  4. 호출 지점에 await 추가

주요 설계 결정

결정근거
기본 단일 스레드가장 자연스러운 코드는 데이터 경합이 없음; 동시성은 옵트인
Async는 호출 액터에 유지데이터 경합 오류를 유발한 암시적 오프로드 제거
격리된 준수MainActor 타입이 안전하지 않은 해결 방법 없이 프로토콜 준수 가능
@concurrent 명시적 옵트인백그라운드 실행은 의도적인 성능 선택이며 우연이 아님
MainActor 기본 추론앱 타겟에 대한 @MainActor 주석 상용구 감소
옵트인 채택중단 없는 마이그레이션 경로 — 기능을 점진적으로 활성화

마이그레이션 단계

  1. Xcode에서 활성화: 빌드 설정에서 Swift 컴파일러 > 동시성 섹션
  2. SPM에서 활성화: 패키지 매니페스트에서 SwiftSettings API 사용
  3. 마이그레이션 도구 사용: swift.org/migration을 통한 자동 코드 변경
  4. MainActor 기본값부터 시작: 앱 타겟에 대해 추론 모드 활성화
  5. 필요한 곳에 @concurrent 추가: 먼저 프로파일링한 후 핫 경로 오프로드
  6. 철저히 테스트: 데이터 경합 문제가 컴파일 타임 오류로 전환됨

모범 사례

  • MainActor에서 시작 — 먼저 단일 스레드 코드를 작성한 후 최적화
  • CPU 집약적 작업에만 @concurrent 사용 — 이미지 처리, 압축, 복잡한 계산
  • 대부분 단일 스레드인 앱 타겟에 MainActor 추론 모드 활성화
  • 오프로드 전에 프로파일링 — Instruments를 사용하여 실제 병목 지점 찾기
  • MainActor로 전역 변수 보호 — 전역/정적 변경 가능 상태는 액터 격리 필요
  • nonisolated 해결 방법이나 @Sendable 래퍼 대신 격리된 준수 사용
  • 점진적으로 마이그레이션 — 빌드 설정에서 기능을 하나씩 활성화

피해야 할 안티 패턴

  • 모든 async 함수에 @concurrent 적용 (대부분 백그라운드 실행이 필요하지 않음)
  • 격리를 이해하지 않고 컴파일러 오류를 억제하기 위해 nonisolated 사용
  • 액터가 동일한 안전성을 제공할 때 레거시 DispatchQueue 패턴 유지
  • 동시성 관련 Foundation Models 코드에서 model.availability 검사 건너뛰기
  • 컴파일러와 싸우기 — 데이터 경합을 보고하면 코드에 실제 동시성 문제가 있는 것
  • 모든 async 코드가 백그라운드에서 실행된다고 가정 (Swift 6.2 기본값: 호출 액터에 유지)

사용 시기

  • 모든 새로운 Swift 6.2+ 프로젝트 (접근 가능한 동시성이 권장 기본값)
  • Swift 5.x 또는 6.0/6.1 동시성에서 기존 앱 마이그레이션
  • Xcode 26 채택 중 데이터 경합 안전성 컴파일러 오류 해결
  • MainActor 중심 앱 아키텍처 구축 (대부분의 UI 앱)
  • 성능 최적화 — 특정 무거운 계산을 백그라운드로 오프로드

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.

관련 스킬