modern-swift について
Swift 6.2 と厳格なコンパイル時チェックを導入する開発者向けの、モダンな Swift 並行処理ガイドです。async/await、アクター、タスクグループ、キャンセル、旧パターンからの移行を解説します。
主な機能
- 01async/await による並行処理パターン
- 02共有可変状態を扱うアクター
- 03タスクグループとキャンセル処理
- 04厳格な並行性チェックと Sendable の指針
- 05従来の並行処理パターンからの移行
活用シーン
- 01完了ハンドラーを async/await に置き換える
- 02ロックを使わず共有状態を管理する
- 03非同期処理を並列実行する
- 04厳格な並行性チェックを有効にして Sendable エラーに対処する
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ johnrogers/ claude-swift-engineering --skill modern-swiftインストール後、Claude Code で/modern-swiftを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/concurrency-essentials.mdmacros.mdmigration-patterns.mdmodern-attributes.mdstrict-concurrency.mdswift6-concurrency.mdtask-cancellation.mdtask-groups.md詳細
モダンな Swift(6.2 以降)
Swift 6.2 では、async/await、アクター、Sendable 制約を使った厳密なコンパイル時並行性チェックが導入され、データ競合を実行時ではなくコンパイル時に防止します。これが、安全な並行処理を実現する Swift の基盤です。
概要
モダンな Swift は、従来の並行処理パターン(完了ハンドラー、DispatchQueue、ロック)を、コンパイラーが強制する安全性に置き換えます。基本原則は、厳密な並行性チェックを有効にしてコンパイルできるコードには、データ競合がないということです。
クイックリファレンス
| 必要なこと | 使用するもの | 使用しないもの |
|---|---|---|
| 非同期処理 | async/await | 完了ハンドラー |
| メインスレッドでの処理 | @MainActor | DispatchQueue.main |
| 共有される可変状態 | actor | ロック、シリアルキュー |
| 並列タスク | TaskGroup | DispatchGroup |
| スレッドセーフティ | Sendable | どこでも使う @unchecked |
基本的なワークフロー
非同期の Swift コードを記述するときは、次の手順に従います。
- 非同期関数に
asyncを付け、awaitで呼び出します - ビューモデルと UI を更新するコードに
@MainActorを適用します - 共有される可変状態には、ロックではなく
actorを使用します - ループ内で
Task.isCancelledを確認するか、Task.checkCancellation()を呼び出します - コンパイル時の安全性を確保するため、Package.swift で厳密な並行性チェックを有効にします
リファレンスの読み込みガイド
内容が必要になる可能性が少しでもある場合は、必ずリファレンスファイルを読み込んでください。 パターンを見落としたり、間違いを犯したりするより、あらかじめコンテキストを把握しておくほうが適切です。
| リファレンス | 読み込むタイミング |
|---|---|
| Concurrency Essentials | 非同期コードの記述、完了ハンドラーの変換、await の使用時 |
| Swift 6 Concurrency | @concurrent、nonisolated(unsafe)、またはアクターパターンの使用時 |
| Task Groups | 複数の非同期処理を並列実行する時 |
| Task Cancellation | 長時間実行される処理やキャンセル可能な処理を実装する時 |
| Strict Concurrency | Swift 6 の厳密モードを有効にする時、または Sendable エラーを修正する時 |
| Macros | @Observable などの Swift マクロを使用または理解する時 |
| Modern Attributes | レガシーコードの移行時、または @preconcurrency、@backDeployed の使用時 |
| Migration Patterns | デリゲートパターンや UIKit ビューをモダン化する時 |
よくある間違い
-
手っ取り早い修正としての
@unchecked Sendable— コンパイラーエラーを抑えるために@unchecked Sendableを使うと、安全性を放棄したことになります。@uncheckedを付けてもエラーが残る場合、コードにデータ競合が発生する可能性があります。根本的な問題を修正してください。 -
呼び出し箇所での
awaitの付け忘れ — 非同期関数の呼び出し時にawaitを忘れるとコンパイラーエラーになります。一方、ループ内でTask.checkCancellation()を呼び出さずにTask.isCancelledを確認しても、キャンセルは黙って無視されます。 -
weakを使わずに非同期ブロックでselfをキャプチャする — 長時間実行される非同期タスクでselfへの強参照を保持すると、deinit が実行されなくなります。クロージャーでは必ず[weak self]を使うか、ライフサイクルを自動管理する.taskを使用してください。 -
タスクのキャンセルを確認しない — 長時間実行される処理では、定期的に
Task.isCancelledを確認するか、Task.checkCancellation()を呼び出してください。そうしないと、キャンセルシグナルは無視されます。 -
UI コードとテストスイートに
@MainActorを付け忘れる —@Publishedプロパティを更新するメインのテスト構造体とビューモデルには@MainActorが必要です。付け忘れると、スレッドをまたいだ変更が黙って許可されます。ビューモデル、ビュー構造体、メインのテスト構造体、および UI に触れるすべての型に@MainActorを適用してください。 -
アクターのリエントラント性による予期しない動作 — アクターメソッド内の
awaitは、一時的にロックを解放することがあります。その間に別のタスクがアクターの状態を変更する可能性があります。awaitの各箇所の間で状態が変化する可能性を前提に、アクターメソッドを設計してください。