swift-data について
swift-data は、clinic のモジュール型 MVVM-C アーキテクチャでデータ層を構築する開発者向けの SwiftData ガイドです。モデル、永続化、同期、エラー処理を扱い、SwiftData の実装を Data 層に集約します。
主な機能
- 01Domain 層と Data 層の分離
- 02SwiftData エンティティとドメインモデルの対応
- 03リポジトリ経由の永続化指針
- 04オフライン優先の同期と競合処理
- 05スキーマ移行とプレビューの実践
活用シーン
- 01SwiftData モデルとリポジトリの設計
- 02キュー書き込みとバックグラウンド同期の構築
- 03ストア障害やスキーマ移行への対応
- 04分離されたインメモリプレビューの作成
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ pproenca/ dot-skills --skill swift-dataインストール後、Claude Code で/swift-dataを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
metadata.jsonassets/templates/_template.mdreferences/_sections.mdcrud-cancel-delete.mdcrud-delete-indexset.mdcrud-dismiss-save.mdcrud-edit-button.mdcrud-insert-context.mdcrud-save-error-handling.mdcrud-sheet-creation.mdcrud-undo-cancel.mdmodel-class-for-persistence.mdmodel-computed-properties.mdmodel-custom-types.mdmodel-defaults.mdmodel-domain-mapping.mdmodel-external-storage.mdmodel-identifiable.mdmodel-initializer.mdmodel-transient.mdpersist-app-group.mdpersist-autosave.mdpersist-container-error-recovery.mdpersist-container-setup.mdpersist-context-environment.mdpersist-enumerate-batch.mdpersist-identifier-transfer.mdpersist-in-memory-config.mdpersist-model-actor.mdpersist-model-macro.md詳細
SwiftData のベストプラクティス — モジュール型 MVVM-C データレイヤー
クリニックのモジュール型 MVVM-C スタックに沿った、SwiftData の包括的なデータモデリング、永続化、同期アーキテクチャ、エラー処理のガイドです。
アーキテクチャとの整合性
このスキルでは、swift-ui-architect が定めるものと同じモジュール型アーキテクチャを適用します。
┌───────────────────────────────────────────────────────────────┐
│ Feature modules: View + ViewModel, no SwiftData imports │
├───────────────────────────────────────────────────────────────┤
│ Domain: models + repository/coordinator/error protocols │
├───────────────────────────────────────────────────────────────┤
│ Data: @Model entities, SwiftData stores, repository impls, │
│ remote clients, retry executor, sync queue, conflict handling │
└───────────────────────────────────────────────────────────────┘
重要な原則: SwiftData の型(@Model、ModelContext、@Query、FetchDescriptor)は、Data 専用の実装コードに配置します。Feature の View/ViewModel は、Domain の型とプロトコル依存関係を使用します。
クリニックのアーキテクチャ契約(iOS 26 / Swift 6.2)
このスキルのすべてのガイダンスは、クリニックのモジュール型 MVVM-C アーキテクチャを前提としています。
- Feature モジュールがインポートするのは
DomainとDesignSystemのみです(Dataや兄弟 Feature はインポートしません) - App ターゲットは集約点であり、
DependencyContainer、具象コーディネーター、Route Shell の配線を所有します Domainは純粋な Swift を保ち、モデルに加えて、リポジトリ、*Coordinating、ErrorRouting、AppErrorの契約を定義しますDataは SwiftData/ネットワーク/同期/再試行/バックグラウンド I/O を所有し、Domain のプロトコルを実装します- 読み取り/書き込みフローでは、デフォルトで stale-while-revalidate 読み取りと楽観的なキュー方式の書き込みを使用します
- ViewModel はリポジトリプロトコルを直接呼び出します(デフォルトのユースケース/インタラクターレイヤーは設けません)
適用する場面
以下の場合に、このガイドラインを参照してください。
@Modelエンティティクラスを定義し、Domain の構造体にマッピングする- Data レイヤーで ModelContainer と ModelContext を設定する
- SwiftData を基盤とするリポジトリプロトコルを実装する
- stale-while-revalidate リポジトリ読み取り(
AsyncStream)を記述する - 楽観的な書き込みと、キュー方式の同期操作を実装する
- エンティティ間のリレーションシップ(一対多、逆方向)を設定する
- API から取得し、同期コーディネーター経由で SwiftData に永続化する
- 保存失敗、ストアの破損、マイグレーションエラーを処理する
- AppError の特性を、一元化されたエラー UI インフラストラクチャにルーティングする
- サンプルデータを使ったプレビュー用インフラストラクチャを構築する
- アプリのアップデートに向けてスキーマのマイグレーションを計画する
ワークフロー
SwiftData を使用する機能を設計またはリファクタリングする場合は、次のワークフローを使用してください。
- Domain の設計:検証ルールや計算ルールを備えた Domain の構造体(
Trip、Friend)を定義します(model-domain-mapping、state-business-logic-placementを参照) - エンティティの設計:マッピングメソッドを備えた
@Modelエンティティクラスを定義します(model-*、model-domain-mappingを参照) - リポジトリプロトコル:Domain レイヤーで定義し、Data レイヤーで SwiftData を使って実装します(
persist-repository-wrapperを参照) - コンテナの配線:エラーリカバリーを設定し、アプリの境界で
ModelContainerを一度だけ構成します(persist-container-setup、persist-container-error-recoveryを参照) - 依存性注入:リポジトリプロトコルを @Environment 経由で注入します(
state-dependency-injectionを参照) - ViewModel:リポジトリプロトコルに処理を直接委譲する @Observable ViewModel を作成します(
state-query-vs-viewmodelを参照) - CRUD フロー:すべての挿入/削除/更新を ViewModel -> Repository 経由にします(
crud-*を参照) - 同期アーキテクチャ:書き込みをキューに入れ、再試行ポリシーを備えた同期コーディネーター経由で実行します(
sync-*を参照) - リレーションシップ:多対リレーションシップを配列としてモデル化し、削除ルールを定義します(
rel-*を参照) - プレビュー:高速に反復できるよう、メモリ内コンテナとサンプルデータを作成します(
preview-*を参照) - スキーマの進化:バージョン付きスキーマでマイグレーションを計画します(
schema-*を参照)
トラブルシューティング
- データが永続化されない ->
persist-model-macro、persist-container-setup、persist-autosave、schema-configuration - バックグラウンドでのインポート後にリストが更新されない ->
query-background-refresh、persist-model-actor - リストが更新されない(同じコンテキスト内) ->
query-property-wrapper、state-wrapper-views - API 同期で重複が発生する ->
schema-unique-attributes、sync-conflict-resolution - モデル変更後の起動時にアプリがクラッシュする ->
schema-migration-recovery、persist-container-error-recovery - 保存の失敗によってデータが通知なく失われる ->
crud-save-error-handling - ネットワークからのデータが古い ->
sync-offline-first、sync-fetch-persist - ウィジェット/拡張機能からデータを参照できない ->
persist-app-group、schema-configuration - データビューのアーキテクチャパターンを選択する ->
state-query-vs-viewmodel、persist-repository-wrapper
優先度別ルールカテゴリ
| 優先度 | カテゴリ | 影響度 | プレフィックス |
|---|---|---|---|
| 1 | データモデリング | CRITICAL | model- |
| 2 | 永続化のセットアップ | CRITICAL | persist- |
| 3 | クエリとフィルタリング | HIGH | query- |
| 4 | CRUD 操作 | HIGH | crud- |
| 5 | 同期とネットワーク | HIGH | sync- |
| 6 | リレーションシップ | MEDIUM-HIGH | rel- |
| 7 | SwiftUI の状態フロー | MEDIUM-HIGH | state- |
| 8 | スキーマとマイグレーション | MEDIUM-HIGH | schema- |
| 9 | サンプルデータとプレビュー | MEDIUM | preview- |
クイックリファレンス
1. データモデリング(CRITICAL)
model-domain-mapping- Domain/Data の境界を越えて、@Model エンティティをドメイン構造体にマッピングするmodel-custom-types- 並行する配列ではなく、カスタム型を使用するmodel-class-for-persistence- SwiftData のエンティティ型にはクラスを使用するmodel-identifiable- UUID を使ってエンティティを Identifiable に準拠させるmodel-initializer- エンティティクラスにカスタムイニシャライザーを用意するmodel-computed-properties- 派生データには計算プロパティを使用するmodel-defaults- エンティティのプロパティに適切なデフォルト値を設定するmodel-transient- 永続化しないプロパティには @Transient を指定するmodel-external-storage- 大きなバイナリデータには外部ストレージを使用する
2. 永続化のセットアップ(CRITICAL)
persist-repository-wrapper- Domain のリポジトリプロトコルの背後に SwiftData をラップするpersist-model-macro- 永続化するすべての型に @Model マクロを適用するpersist-container-setup- App レベルで ModelContainer を構成するpersist-container-error-recovery- ストアを復旧して ModelContainer の作成失敗に対処するpersist-context-environment- @Environment を介して ModelContext にアクセスする(Data レイヤー)persist-autosave- 手動で作成したコンテキストで自動保存を有効にするpersist-enumerate-batch- 大規模な走査には ModelContext.enumerate を使用するpersist-in-memory-config- テストとプレビューにはメモリ内構成を使用するpersist-app-group- 共有データストレージには App Groups を使用するpersist-model-actor- バックグラウンドで SwiftData を処理するには @ModelActor を使用するpersist-identifier-transfer- PersistentIdentifier をアクター間で渡す
3. クエリとフィルタリング(高)
query-property-wrapper- 宣言的なデータ取得には @Query を使用する(データレイヤー)query-background-refresh- バックグラウンドコンテキストへの挿入後にビューを強制的に更新するquery-sort-descriptors- @Query にソート記述子を適用するquery-predicates- 型安全なフィルタリングには #Predicate を使用するquery-dynamic-init- 動的なクエリにはカスタムのビュー初期化子を使用するquery-fetch-descriptor- SwiftUI ビューの外で FetchDescriptor を使用するquery-fetch-tuning- FetchDescriptor のページングと保留中の変更の動作を調整するquery-localized-search- 検索には localizedStandardContains を使用するquery-expression- 再利用可能な述語コンポーネントには #Expression を使用する(iOS 18+)
4. CRUD 操作(高)
crud-insert-context- リポジトリの実装を通じてモデルを挿入するcrud-delete-indexset- onDelete から渡される IndexSet を使って、リポジトリ経由で削除するcrud-sheet-creation- ViewModel を通じて、対象を絞ったデータ作成にシートを使用するcrud-cancel-delete- 保存時にのみ永続化して、孤立レコードを防ぐcrud-undo-cancel- 元に戻す機能を有効にして、編集のキャンセルに使用するcrud-edit-button- リスト管理用に EditButton を提供するcrud-dismiss-save- ViewModel の保存完了後にモーダルを閉じるcrud-save-error-handling- ユーザーにフィードバックを提示して、リポジトリの保存失敗に対処する
5. 同期とネットワーク(高)
sync-fetch-persist- 注入された同期サービスを使って API データを取得し、永続化するsync-offline-first- リポジトリからの読み取りとバックグラウンド同期を使って、オフラインファーストのアーキテクチャを設計するsync-conflict-resolution- 双方向同期の競合解決を実装する
6. リレーションシップ(中〜高)
rel-optional-single- オプショナルなリレーションシップにはオプショナル型を使用するrel-array-many- 1 対多のリレーションシップには配列を使用するrel-inverse-auto- SwiftData による逆リレーションシップの自動管理を利用するrel-delete-rules- 所有するリレーションシップにカスケード削除ルールを設定するrel-explicit-sort- リレーションシップの配列を明示的にソートする
7. SwiftUI の状態フロー(中〜高)
state-query-vs-viewmodel- すべてのデータアクセスを @Observable ViewModel 経由にするstate-business-logic-placement- ドメインの値型とリポジトリを利用する ViewModel にビジネスロジックを配置するstate-dependency-injection- @Environment を通じてリポジトリのプロトコルを注入するstate-bindable- 双方向のモデルバインディングには @Bindable を使用するstate-local-state- ビュー内のみで使う一時データには @State を使用するstate-wrapper-views- 動的なクエリ状態のためにラッパービューを切り出す
8. スキーマとマイグレーション(中〜高)
schema-define-all-types- すべてのモデル型を使ってスキーマを定義しますschema-unique-attributes- 自然キーには @Attribute(.unique) を使用しますschema-unique-macro- 複合一意性には #Unique を使用します(iOS 18 以降)schema-index- 頻繁に使用する述語と並べ替えには #Index を使用します(iOS 18 以降)schema-migration-plan- モデルを変更する前にマイグレーションを計画しますschema-migration-recovery- スキーマ変更に備えてマイグレーションからの復旧を計画しますschema-configuration- ModelConfiguration を使ってストレージをカスタマイズします
9. サンプルデータとプレビュー(中)
preview-sample-singleton- プレビュー用に SampleData シングルトンを作成しますpreview-in-memory- プレビューを分離するためにインメモリコンテナを使用しますpreview-static-data- モデル型に静的なサンプルデータを定義しますpreview-main-actor- SampleData に @MainActor を付与します
使用方法
詳しい説明とコード例については、各リファレンスファイルをお読みください。
- セクションの定義 - カテゴリー構成と影響レベル
- ルールのテンプレート - 新しいルールを追加するためのテンプレート
リファレンスファイル
| ファイル | 説明 |
|---|---|
| references/_sections.md | カテゴリーの定義と順序 |
| assets/templates/_template.md | 新しいルール用のテンプレート |
| metadata.json | バージョンとリファレンス情報 |
コメント
Markdown 対応