swiftui-patterns について
swiftui-patternsは、iOS 17以降のSwiftUI開発者向けリファレンススキルです。状態、環境、ナビゲーション、非同期処理に使う最新のApple APIと、よくある問題を案内します。
主な機能
- 01iOS 17以降の状態と環境のパターン
- 02.taskによる非同期処理
- 03NavigationStackとNavigationPathのガイダンス
- 04アクセシビリティとUIKit連携の案内
活用シーン
- 01SwiftUIモデルの状態ラッパーの選択
- 02iOS 16のパターンからiOS 17以降への移行
- 03非同期読み込みとナビゲーションの実装
- 04アクセシビリティやUIKitラッパーの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ johnrogers/ claude-swift-engineering --skill swiftui-patternsインストール後、Claude Code で/swiftui-patternsを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/accessibility.mdasync-patterns.mdcomposition.mdenvironment.mdmigration-guide.mdmvvm-observable.mdnavigation.mdobservable.mdperformance.mdstate-management.mduikit-interop.mdview-modifiers.md詳細
SwiftUI パターン(iOS 17 以降)
SwiftUI 17 以降では、@Observable によって ObservableObject の定型コードが不要になり、@Environment によって環境への注入が簡素化され、タスクベースの非同期パターンが導入されています。基本原則は、リアクティブライブラリではなく Apple の最新 API を使うことです。
概要
クイックリファレンス
| 必要なもの | 使用するもの(iOS 17 以降) | 使用しないもの |
|---|---|---|
| Observable モデル | @Observable | ObservableObject |
| Published プロパティ | 通常のプロパティ | @Published |
| 所有する状態 | @State | @StateObject |
| 渡されたモデル(バインディング) | @Bindable | @ObservedObject |
| 環境への注入 | environment(_:) | environmentObject(_:) |
| 環境へのアクセス | @Environment(Type.self) | @EnvironmentObject |
| 表示時の非同期処理 | .task { } | .onAppear { Task {} } |
| 値の変更 | onChange(of:initial:_:) | onChange(of:perform:) |
基本的なワークフロー
- モデルクラスには
@Observableを使います(@Published は不要です) - ビューが所有するモデルには
@State、渡されたモデルには@Bindableを使います - 非同期処理には
.task { }を使います(ビューが消えると自動的にキャンセルされます) - プログラムによるナビゲーションには、
NavigationPathとNavigationStackを使います - インタラクティブな要素には
.accessibilityLabel()と.accessibilityHint()を適用します
リファレンスの読み込みガイド
内容が必要になる可能性が少しでもある場合は、必ずリファレンスファイルを読み込んでください。 パターンを見落としたり、間違いを犯したりするより、事前にコンテキストを把握しておくほうが適切です。
| リファレンス | 読み込むタイミング |
|---|---|
| Observable | 新しい @Observable モデルクラスを作成するとき |
| 状態管理 | @State、@Bindable、@Environment のどれを使うか判断するとき |
| 環境 | ビュー階層に依存関係を注入するとき |
| ビュー修飾子 | onChange、task、または iOS 17 以降の修飾子を使うとき |
| 移行ガイド | iOS 16 のコードを iOS 17 以降に更新するとき |
| MVVM Observable | ビューモデルのアーキテクチャを設定するとき |
| ナビゲーション | プログラムによるナビゲーションまたはディープリンクを実装するとき |
| パフォーマンス | 100 件を超える項目を含むリストや、過剰な再描画に対処するとき |
| UIKit 連携 | UIKit コンポーネント(WKWebView、PHPicker)をラップするとき |
| アクセシビリティ | VoiceOver、Dynamic Type、アクセシビリティアクションを扱うとき |
| 非同期パターン | 読み込み状態、更新、バックグラウンドタスクを扱うとき |
| コンポジション | 再利用可能なビュー修飾子や複雑な条件付き UI を扱うとき |
よくある間違い
-
渡されたモデルに
@Bindableを使いすぎる — すべてのプロパティに@Bindableを作成すると、不要なビューの再読み込みが発生します。双方向バインディングが必要な変更可能なモデルプロパティにのみ@Bindableを使います。読み取り専用の計算プロパティには通常のプロパティを使います。 -
状態を配置する場所の誤り — 専用の
@Observableモデルではなくビューにモデルの状態を置くと、ビューのロジックが複雑に絡み合います。モデルとビューの関心事は必ず分離してください。 -
NavigationPath の状態破損 —
NavigationPathを誤って変更すると、一貫性のない状態になることがあります。パスの破損を防ぐため、適切な状態管理とともにnavigationDestination(for:destination:)を使います。 -
.taskのキャンセル漏れ —.taskはビューが消えたときに自動でキャンセルしますが、ネストされた Task は対象外です。複雑な非同期処理フローでは、ゾンビタスクを防ぐために明示的なキャンセル追跡が必要です。 -
環境の無効化を無視する — 親で環境値を変更しても、子ビューが自動的に無効化されるわけではありません。
@Environmentを一貫して使い、観測に基づいて再描画が発生するタイミングを理解してください。 -
UIKit 連携によるメモリリーク — デリゲートの循環参照を解消しないと、
UIViewRepresentableとUIViewControllerRepresentableでメモリリークが発生することがあります。弱参照と明示的なクリーンアップが必要です。