Awesome-omni-skill swift-actor-persistence
Use when building a thread-safe data persistence layer in Swift using actors with in-memory cache and file storage.
install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data-ai/swift-actor-persistence" ~/.claude/skills/diegosouzapw-awesome-omni-skill-swift-actor-persistence-69c4c1 && rm -rf "$T"
manifest:
skills/data-ai/swift-actor-persistence/SKILL.mdsource content
Swift Actors for Thread-Safe Persistence
スレッドセーフな永続化のためのSwift Actor
Extracted / 抽出日: 2026-02-05 Context / コンテキスト: iOS/Swift apps requiring thread-safe data persistence with async/await async/awaitを使用したスレッドセーフなデータ永続化が必要なiOS/Swiftアプリ
Problem / 課題
Data persistence layers often face race conditions when multiple parts of an app read/write simultaneously. Traditional approaches (DispatchQueues, locks) are error-prone and verbose.
データ永続化レイヤーは、アプリの複数の部分が同時に読み書きする際にレースコンディションに直面することが多い。従来のアプローチ(DispatchQueues、ロック)はエラーが発生しやすく、冗長になりがち。
Solution / 解決策
Use Swift actors to isolate all persistence state and operations. The actor model guarantees:
- No data races (compiler-enforced)
- Automatic serialization of access
- Async-first API that integrates with structured concurrency
Swift actorを使用して、すべての永続化状態と操作を分離する。actorモデルは以下を保証:
- データ競合なし(コンパイラによる強制)
- アクセスの自動シリアライズ
- 構造化並行性と統合されたasyncファーストAPI
public actor LocalRepository { private var cache: [String: Record] = [:] private let cacheFileURL: URL public init(directory: URL = .documentsDirectory) { self.cacheFileURL = directory.appendingPathComponent("cache.json") // Synchronous cache load during init (actor isolation not yet active) // init中の同期キャッシュ読み込み(actor分離がまだアクティブでないため) self.cache = Self.loadCacheSynchronously(from: cacheFileURL) } public func save(_ record: Record) throws { cache[record.id] = record try persistToFile() } public func loadAll() -> [Record] { Array(cache.values) } public func find(by id: String) -> Record? { cache[id] } private func persistToFile() throws { let data = try JSONEncoder().encode(Array(cache.values)) try data.write(to: cacheFileURL) } private static func loadCacheSynchronously(from url: URL) -> [String: Record] { guard let data = try? Data(contentsOf: url), let records = try? JSONDecoder().decode([Record].self, from: data) else { return [:] } return Dictionary(uniqueKeysWithValues: records.map { ($0.id, $0) }) } }
Key Patterns / 主要パターン
- In-memory cache + file persistence / インメモリキャッシュ + ファイル永続化: Fast reads from cache, durable writes to disk / キャッシュからの高速読み取り、ディスクへの永続書き込み
- Synchronous init loading / 同期的な初期化読み込み: Avoids async initialization complexity / 非同期初期化の複雑さを回避
- Dictionary keying / Dictionary型によるキー管理: O(1) lookups by ID / IDによるO(1)の検索
- Private persistence / プライベートな永続化: External callers only see domain operations / 外部呼び出し元はドメイン操作のみを参照
Usage / 使用方法
let repository = LocalRepository() // All calls are async due to actor isolation // actor分離により、すべての呼び出しは非同期 let records = await repository.loadAll() try await repository.save(newRecord) let found = await repository.find(by: "question-1")
When to Use / 使用すべき場面
- Building a data persistence layer in Swift 5.5+ / Swift 5.5以降でデータ永続化レイヤーを構築する場合
- Need thread-safe access to shared state / 共有状態へのスレッドセーフなアクセスが必要な場合
- Want to avoid manual synchronization (locks, queues) / 手動同期(ロック、キュー)を避けたい場合
- Building offline-first apps with local storage / ローカルストレージを使用したオフラインファーストアプリを構築する場合
Related Patterns / 関連パターン
- Combine with
ViewModels for UI binding / UIバインディング用に@Observable
ViewModelと組み合わせる@Observable - Use
types for data crossing actor boundaries / actor境界を越えるデータにはSendable
型を使用Sendable - Consider
actor for cloud sync operations / クラウド同期操作にはFileBasedSyncManager
actorを検討FileBasedSyncManager