Communitygithub.com

swift-concurrency-6-2

Swift 6.2 접근 가능한 동시성(Approachable Concurrency) — 기본적으로 단일 스레드에서 실행되며, 명시적인 @concurrent를 통한 백그라운드 오프로딩, 메인 액터 타입을 위한 격리된 프로토콜 적합성(isolated conformance)을 제공합니다. Swift 6.2 동시성 모델을 채택할 때 @concurrent로 작업을 오프로딩하거나 메인 액터 격리 문제를 해결할 때 사용하세요.

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

SKILL.md는 Apple Swift 6.2에 도입된 '접근 가능한 동시성(Approachable Concurrency)' 모델을 설명합니다. 기존 Swift 동시성 모델(6.1 이하)은 async 함수가 암시적으로 백그라운드 스레드로 오프로딩되어 데이터 경합 오류를 일으키는 문제가 있었습니다. Swift 6.2는 이러한 문제를 해결하여, async 함수가 기본적으로 호출하는 액터(예: MainActor) 위에 머물도록 변경했습니다. 이를 통해 가장 일반적인 코드는 데이터 경합으로부터 안전해지며, 동시성은 명시적인 선택 사항이 됩니다. 이 스킬은 Swift 5.x, 6.0, 6.1 프로젝트를 Swift 6.2로 마이그레이션하거나, 새로운 프로젝트를 시작할 때 유용합니다. 주요 패턴으로는 '격리된 프로토콜 적합성(Isolated Conformances)'을 통해 @MainActor 타입이 프로토콜을 안전하게 준수할 수 있게 하고, '전역 및 정적 변수'를 MainActor로 보호하며, '@concurrent' 어노테이션을 통해 CPU 집약적인 작업을 명시적으로 백그라운드 스레드로 오프로딩하는 방법을 제공합니다. 또한, 타겟 전체에 @MainActor를 자동으로 유추하는 'MainActor 기본 유추 모드'를 선택적으로 활성화할 수 있어, UI 앱과 같은 대부분 단일 스레드로 동작하는 앱의 보일러플레이트 코드를 줄여줍니다. Xcode 26, SPM 등에서 설정을 활성화하여 단계적으로 마이그레이션할 것을 권장합니다.

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

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

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

문서

Swift 6.2 접근 가능한 동시성 (Approachable Concurrency)

Swift 6.2의 동시성 모델을 채택하기 위한 패턴입니다. 이 모델에서는 코드가 기본적으로 단일 스레드에서 실행되며, 동시성은 명시적으로 도입됩니다. 일반적인 데이터 경합 오류를 제거하면서도 성능을 희생하지 않습니다.

활성화 시점

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

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

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)
    }
}

핵심 패턴 — 격리된 적합성 (Isolated Conformances)

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

protocol Exportable {
    func export()
}

// Swift 6.1: 오류 — MainActor 격리 코드로 교차됩니다
// Swift 6.2: 격리된 적합성(isolated conformance)으로 OK
nonisolated func exportStickers(_ items: [any Exportable]) {
    for item in items {
        item.export() // 오류: @MainActor 적합성은 이곳에서 사용할 수 없습니다
    }
}

컴파일러는 적합성이 MainActor에서만 사용되도록 보장합니다:

// 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 기본 유추 모드 (MainActor Default Inference Mode)

Swift 6.2는 MainActor가 기본적으로 유추되는 모드를 도입합니다 — 수동 어노테이션이 필요 없습니다:

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

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

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

이 모드는 선택 사항이며, 앱, 스크립트 및 기타 실행 가능한 타겟에 권장됩니다.

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

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

중요: 이 예제는 접근 가능한 동시성 빌드 설정(SE-0466 MainActor 기본 격리 및 SE-0461 Nonisolated Nonsending by Default)이 필요합니다. 이러한 설정이 활성화되면 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/claude-api

Anthropic Claude API patterns for Python and TypeScript. Covers Messages API, streaming, tool use, vision, extended thinking, batches, prompt caching, and Claude Agent SDK. Use when building applications with the Claude API or Anthropic SDKs.

affaan-m/everything-claude-code

End-to-end marketing campaign planning and execution. Covers audience research, positioning, campaign angle definition, landing page copy, email sequences, social posts, ad copy, short-form video scripts, and content calendars. Use as the orchestration layer for multi-channel product launches. Use when planning or executing a multi-channel product launch, or producing landing page, email, social, or ad copy.

affaan-m/everything-claude-code

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/everything-claude-code-conventions

Development conventions and patterns for everything-claude-code. JavaScript project with conventional commits.

affaan-m/frontend-design

Create distinctive, production-grade frontend interfaces with high design quality. Use when the user asks to build web components, pages, or applications and the visual direction matters as much as the code quality.

affaan-m/gget

gget CLI and Python workflow for quick genomic database queries, sequence lookup, BLAST-style searches, enrichment checks, and reproducible bioinformatics evidence logs.

affaan-m/literature-review

Systematic literature-review workflow for academic, biomedical, technical, and scientific topics, including search planning, source screening, synthesis, citation checks, and evidence logging.

affaan-m/motion-ui

Production-ready UI motion system for React/Next.js. Use when implementing animations, transitions, or motion patterns.

affaan-m/project-guidelines-example

Example project-specific skill template based on a real production application.

affaan-m/pubmed-database

Direct PubMed and NCBI E-utilities search workflows for biomedical literature, MeSH queries, PMID lookup, citation retrieval, and API-backed literature monitoring.

affaan-m/scholar-evaluation

Structured scholarly-work evaluation for papers, proposals, literature reviews, methods sections, evidence quality, citation support, and research-writing feedback.

affaan-m/uspto-database

USPTO patent and trademark data workflow for official record lookup, PatentSearch queries, TSDR checks, assignment data, and reproducible IP research logs.

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.

관련 스킬