SwiftDataとCloudKitの連携メモ
SwiftDataとCloudKitの連携について実際に試してみたのでメモ。
やりたいこと
SwiftDataで保存したデータをiCloud上に保存し、他の端末と同期させる。
環境
Xcode 26.0.1
Swift 5
iOS 26
macOS Tahoe 26.0.1
新規プロジェクト作成
StorageでSwiftDataを選択し、Host in CloudKitにチェックを入れる。
Host in CloudKitにチェックを入れた時の差分は下記の通り。
Signing & CapabilitiesにBackground ModesとiCloudが追加されている
Background ModesではRemote Notificationsにチェックが入っている
iCloudではCloudKitにチェックが入っている
Host in CloudKitのチェックを入れてない状態のプロジェクトの場合は上記の変更を加えればOK。
Signing & Capabilitiesの設定
Sigining & CapabilitiesのiCloudのセクションにあるContainersで+ボタンをクリックし、新たにiCloud Containerを作成する。
iCloud ContainerのIdentifierはドキュメントを見た感じ先頭に「iCloud.」を付けていたのでそれに則って命名して作成。
今回は「iCloud.[Bundle ID]」の形で命名した。
この状態でビルドするとコンソールにエラーが流れる。
Unresolved error loading container Error Domain=NSCocoaErrorDomain Code=134060 "A Core Data error occurred." UserInfo={NSLocalizedFailureReason=CloudKit integration requires that all attributes be optional, or have a default value set. The following attributes are marked non-optional but do not have a default value:
Item: timestamp}CloudKitと連携する場合、Modelのパラメーターはoptionalかデフォルト値の設定が必要とのこと。
Itemのtimestampにデフォルト値を設定する。
// Item.swift
import Foundation
import SwiftData
@Model
final class Item {
var timestamp: Date = Date()
init(timestamp: Date) {
self.timestamp = timestamp
}
}修正後、改めてビルドすると無事アプリが立ち上がった。
シミュレーター上の設定アプリからApple Accountにログインした状態で試しにタイムスタンプをいくつか追加してみる。
その後、同じApple Accountでログインしている実機端末でアプリをビルドして確認したところ、データの同期ができているのが確認できた。
CloudKitとの同期を切りたい場合
modelConfigurationのcloudKitDatabaseを.noneにすると端末に保存されているデータはそのまま、CloudKitとの同期を切ることができる。
let modelConfiguration = ModelConfiguration(schema: schema, isStoredInMemoryOnly: false, cloudKitDatabase: .none)CloudKit ConsoleでiCloudに保存されたデータを確認する
CloudKit ConsoleはSigning & CapabilitilesのiCloudセクションにあるCloudKit Consoleから開くことができる。
開いたら左上のCloudKit Databaseを選択。

ページの左上から今回作成したiCloud Containerを選択し、左のカラムのDataセクションからRecordsを選択。
各項目は下記のように設定。
DB: Private Database
Zone: com.apple.coredata.cloudkit.zone
Query Records
RECORD TYPE: CD_Item
FIELDS: All
設定できたらQuery Recordsボタンをクリック。

すると「Field 'recordName' is not marked queryable」というエラーが発生。

IndexesにrecordNameというフィールドがqueryableとして登録されていないのが原因なので追加する。
左のカラムのSchemaセクションからIndexesを選択。
Indexesのタイトル横の+ボタンをクリックしAdd Index画面を開いて下記のように入力。
Record Type: CD_Item
Name: recordName
Type: QUERYABLE
Field: recordName

AddボタンをクリックするとIndexesのCD_Item配下にrecordNameが追加される。

これでRecordsに戻って先ほどと同じクエリを実行するとiCloudに保存されているItemが表示される。
その他メモと気になったこと(追々調べる)
Modelの制約は他にもあるようで、気を付ける必要がある
ドキュメントには@Attribute、@Relationshipについての記載がある
リリースする際は別途CloudKit Consoleでデプロイ作業が必要
保存したデータがある状態でModelのパラメータを変更した場合どうなる?
CloudKit Consoleで保存したデータを確認する際、今回Development環境だから自分が保存したレコードだけ表示されたが、本番環境だとどうなる?
