Communitygithub.com

swift-actor-persistence

Swift 액터를 사용한 스레드 안전 데이터 영속성 – 인메모리 캐시와 파일 기반 스토리지를 결합하여 설계 단계에서 데이터 경합을 제거합니다. Swift에서 데이터를 영속화하면서 데이터 경합이나 스레드 안전성 문제를 설계적으로 해결해야 할 때 사용합니다.

swift-actor-persistence란 무엇인가요?

이 스킬은 Swift 5.5+에서 액터 모델을 사용하여 스레드 안전한 데이터 영속성 계층을 구축하는 방법을 제공합니다. 인메모리 캐시와 파일 기반 스토리지를 결합함으로써 컴파일 타임에 데이터 경합을 제거합니다. iOS/macOS 앱 개발 시 로컬 데이터 저장, 오프라인 우선 아키텍처, 여러 부분에서 동시에 접근하는 공유 가변 상태 관리에 유용합니다. 주요 사용 방법은 액터 기반 리포지토리 패턴을 따르며, 모든 호출은 액터 격리로 인해 자동으로 비동기(async) 처리됩니다. `@Observable` ViewModel과 결합하여 반응형 UI 업데이트를 구현할 수 있으며, 원자적 파일 쓰기(.atomic)를 통해 충돌 시 데이터 손상을 방지합니다.

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

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

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

문서

스레드 안전 영속성을 위한 Swift 액터

Swift 액터를 사용하여 스레드 안전한 데이터 영속성 계층을 구축하기 위한 패턴입니다. 인메모리 캐싱과 파일 기반 스토리지를 결합하며, 액터 모델을 활용하여 컴파일 타임에 데이터 경합을 제거합니다.

활성화 시점

  • Swift 5.5+에서 데이터 영속성 계층을 구축할 때
  • 공유 가변 상태에 대한 스레드 안전 접근이 필요할 때
  • 수동 동기화(lock, DispatchQueue)를 없애고 싶을 때
  • 로컬 저장소를 사용하는 오프라인 우선 앱을 구축할 때

핵심 패턴

액터 기반 리포지토리

액터 모델은 직렬화된 접근을 보장합니다. 데이터 경합이 없으며, 컴파일러가 강제합니다.

public actor LocalRepository<T: Codable & Identifiable> where T.ID == String {
    private var cache: [String: T] = [:]
    private let fileURL: URL

    public init(directory: URL = .documentsDirectory, filename: String = "data.json") {
        self.fileURL = directory.appendingPathComponent(filename)
        // init 중 동기적 로드 (액터 격리가 아직 활성화되지 않음)
        self.cache = Self.loadSynchronously(from: fileURL)
    }

    // MARK: - 공개 API

    public func save(_ item: T) throws {
        cache[item.id] = item
        try persistToFile()
    }

    public func delete(_ id: String) throws {
        cache[id] = nil
        try persistToFile()
    }

    public func find(by id: String) -> T? {
        cache[id]
    }

    public func loadAll() -> [T] {
        Array(cache.values)
    }

    // MARK: - 비공개

    private func persistToFile() throws {
        let data = try JSONEncoder().encode(Array(cache.values))
        try data.write(to: fileURL, options: .atomic)
    }

    private static func loadSynchronously(from url: URL) -> [String: T] {
        guard let data = try? Data(contentsOf: url),
              let items = try? JSONDecoder().decode([T].self, from: data) else {
            return [:]
        }
        return Dictionary(uniqueKeysWithValues: items.map { ($0.id, $0) })
    }
}

사용법

액터 격리로 인해 모든 호출은 자동으로 비동기(async)입니다:

let repository = LocalRepository<Question>()

// 읽기 — 인메모리 캐시에서 빠른 O(1) 조회
let question = await repository.find(by: "q-001")
let allQuestions = await repository.loadAll()

// 쓰기 — 캐시를 업데이트하고 파일에 원자적으로 영속화
try await repository.save(newQuestion)
try await repository.delete("q-001")

@Observable ViewModel과 함께 사용하기

@Observable
final class QuestionListViewModel {
    private(set) var questions: [Question] = []
    private let repository: LocalRepository<Question>

    init(repository: LocalRepository<Question> = LocalRepository()) {
        self.repository = repository
    }

    func load() async {
        questions = await repository.loadAll()
    }

    func add(_ question: Question) async throws {
        try await repository.save(question)
        questions = await repository.loadAll()
    }
}

주요 설계 결정 사항

결정 사항근거
액터 (클래스 + lock 대신)컴파일러가 강제하는 스레드 안전성, 수동 동기화 불필요
인메모리 캐시 + 파일 영속성캐시에서 빠른 읽기, 디스크에 안정적 쓰기
init의 동기적 로딩비동기 초기화의 복잡성 회피
ID로 키를 지정한 딕셔너리식별자로 O(1) 조회
Codable & Identifiable에 대한 제네릭모든 모델 타입에서 재사용 가능
원자적 파일 쓰기 (.atomic)충돌 시 부분 쓰기 방지

모범 사례

  • 액터 경계를 넘는 모든 데이터에 Sendable 타입 사용
  • 액터의 공개 API를 최소화 — 영속성 세부 사항이 아닌 도메인 연산만 노출
  • .atomic 쓰기를 사용하여 충돌 시 데이터 손상을 방지
  • init에서는 동기적 로딩 — 비동기 초기화는 로컬 파일의 경우 이점이 거의 없으면서 복잡성만 증가
  • 반응형 UI 업데이트를 위해 @Observable ViewModel과 결합

피해야 할 안티 패턴

  • 새로운 Swift 동시성 코드에서 액터 대신 DispatchQueue 또는 NSLock 사용
  • 내부 캐시 딕셔너리를 외부 호출자에게 노출
  • 검증 없이 파일 URL을 설정 가능하게 만듦
  • 모든 액터 메서드 호출이 await임을 잊음 — 호출자는 async 컨텍스트를 처리해야 함
  • nonisolated를 사용하여 액터 격리를 우회 (목적을 무력화함)

사용 시기

  • iOS/macOS 앱의 로컬 데이터 저장 (사용자 데이터, 설정, 캐시된 콘텐츠)
  • 나중에 서버와 동기화하는 오프라인 우선 아키텍처
  • 앱의 여러 부분이 동시에 접근하는 공유 가변 상태
  • 레거시 DispatchQueue 기반 스레드 안전성을 최신 Swift 동시성으로 대체

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.

관련 스킬