💽

SwiftData + CloudKit で iCloud同期 を実装する(備忘録)

に公開

最終更新:2025/11/21

はじめに

SwiftData を使って iCloud同期 を実装するための情報がまとまってなかったので、備忘録を兼ねてここで書いていきます。
実際に以下の手順で自分の開発しているアプリ内で実装しました。
まだまだ初心者なので、間違い等ご容赦ください。

使用した環境

  • Xcode ver.26.0 (17A324)
  • シミュレーター
    • iOS 26.0
  • 実機(TestFlight)
    • iPhone 17 (iOS 26.0.1)
    • iPad (第9世代) (iOS 26.0)

1. XcodeでCloudKitの機能を有効化

  • Xcodeの 「TARGET」「Signing & Capabilities」 へ移動


右の欄にiCloudがない場合のみ

  • 左上の 「+ Capability」 をクリックする。

  • 表示されるウィンドウの検索欄に 「icloud」 と入力し、ヒットした 「iCloud」 を選択する。

  • これでiCloudの欄が追加されます。

  • 「CloudKit」 にチェック。
  • 下の 「+」 ボタンをクリック

  • container の identifier を入力するように言われるので、値(一般的に iCloud.自分のアプリのBundleID)を入力してコンテナを作成する。

  • iCloudの欄の上の方にある 「Background Modes」「Remote notifications」 にチェック。

Background Modes の Remote notifications はどのようなもの?

ユーザーにバナー等を見せずに、新着データの取得・同期・キャッシュ更新などをバックグラウンドで行うための権限。

2. モデルをCloudKit互換に整える

以下に示すものはCloudKit連携の制約で、満たさないと起動時にエラーになってしまうようです。

  • 非オプショナル属性にはデフォルト値を与える or Optionalにする。

  • Unique制約(@Attribute(.unique))は使わない(CloudKit非対応)。

  • リレーションは基本Optionalに。

@Model
final class Card {
    var title: String = ""
    
    @Relationship(deleteRule: .cascade) 
    var photos: [Photo]?
}

3. ModelContainerを用意

Appのエントリで .modelContainer(for:) を用意する。

@main
struct CardApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .modelContainer(for: Card.self)
    }
}

SwiftData はエンタイトルメントを見て自動で CloudKit を使うため、基本はこれだけでOKです
必要に応じて特定コンテナを明示することもあるようです。

4. ビルドして開発用スキーマを生成

CloudKit の開発環境(Development)でアプリを一度動かし、CloudKit に最初のレコードを書き込ませて開発環境にスキーマを自動作成していきます。

スキーマ(Schema)とは?

CloudKitがレコードを保存・同期するための設計図。「どんなレコードタイプ(テーブルに相当)があり」「各フィールド(列)にどんな型や制約があるか」というような、レコードやフィールドの定義のこと。

  • シミュレーター(または実機端末)上で iCloud にサインインした チームメンバーのApple アカウントにログインする(開発環境にアクセスできるのはチームメンバー(開発者)のみ)。 

  • アプリ内で SwiftData 経由でオブジェクトを1件以上保存する。

  • この保存がトリガーとなって、CloudKit の Development 環境にスキーマが自動作成されます。 

5. CloudKit Consoleで中身を確認

  • 以下のリンクから CloudKit Console にログインする。

https://icloud.developer.apple.com

  • 「CloudKit Database」 をクリックする。

  • Environment が Development であることを確認し、SchemaRecord Types にレコードがあるか確認する(SwiftDataで定義したものが出ている確認する)。

6. スキーマをProductionにデプロイ

  • 左下の 「Deploy Schemea Changes...」 をクリックして、Development(開発環境)で生成されたスキーマを Production(本番環境)へ Deploy する。

7. テスト

  • 同一Apple IDの複数端末でアプリをインストール → 片方で作成/編集 → 数秒〜十数秒で自動同期されることを確認する。

  • 以上で、SwiftData と CloudKit による iCloud同期の実装は完了です!お疲れ様でした!

手動同期をしたり、同期状況を表示することはできる?

どうやら SwiftData には、手動で同期を行ったり、同期状況(進捗や最終同期時刻)を表示したりするAPIはないようです。
そのような機能を実装したい場合は、CoreDataを利用する必要がありそうです。

8. その他注意点

CloudKit は 1レコードあたり1MBのサイズ上限があります
アセット(CKAsset)はこの制限の対象外(別領域)なので、画像などを扱う場合は別モデルに分離し、Data?@Attribute(.externalStorage) で保持するのが良さそう?

おわりに

どなたかの参考になっていれば幸いです!

参考資料

1.

https://developer.apple.com/documentation/CoreData/setting-up-core-data-with-cloudkit

https://zenn.dev/treastrain/articles/9db1ac5fb17904?utm_source=chatgpt.com

2.

https://firewhale.io/posts/swift-data-quirks/?utm_source=chatgpt.com

3.

https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices
https://developer.apple.com/documentation/swiftdata/modelcontainer?utm_source=chatgpt.com

4.

https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices

https://developer.apple.com/library/archive/documentation/General/Conceptual/iCloudDesignGuide/DesigningforCloudKit/DesigningforCloudKit.html?utm_source=chatgpt.com

5.

https://developer.apple.com/videos/play/wwdc2021/10117/?utm_source=chatgpt.com

6.

https://developer.apple.com/documentation/cloudkit/managing-icloud-containers-with-cloudkit-database-app?utm_source=chatgpt.com

7.

https://developer.apple.com/documentation/swiftdata/syncing-model-data-across-a-persons-devices

8.

https://developer.apple.com/documentation/cloudkit/ckrecord?language=objc&utm_source=chatgpt.com

Discussion