[SwiftUI][CoreData] SwiftUI と MVVM で始める CoreData 入門 (その15:iCloud 同期)

SwiftUI と CoreData を組み合わせたアプリの作り方を説明します。

環境&対象

以下の環境で動作確認を行なっています。

  • maxOS Catalina 10.15.7
  • Xcode 12.3
  • iOS 14.2

前回は、CoreData を Realm に置き換えて動かしてみました。
[SwiftUI][CoreData] SwiftUI と MVVM で始める CoreData 入門 (その14:CoreData を Realm と入れ替え)

今回は、CoreData 版を拡張して、iCloud 同期できるようにします。

注意
CloudKit を使った開発をするには、Apple Developer Program への加入が必要です。

iCloud 同期

複数のデバイスで同じデータを使うためには、2種類の方法があります。
1つ目は、iCloud 上にドキュメントファイルを置き、複数のデバイスから開く方法です。

アプリを Document App で作成すると実現できます。

しかし、CoreData と相性は良くないです。
SwiftUI[SwiftUI] Document App の隠れた制約(FileDocument の制約)

もう1つの方法が今回実装する CloudKit を使う方法です。アプリが自動的に iCloud と同期してくれます。

NSPersistentCloudKitContainer

NSPersistentContainer の CloudKit 対応版です。

Apple のドキュメントは、こちら

NSPersistentContainer の代わりに、NSPersistentCloudKitContainer を使うことで、自動的に iCloud と Sync されます。

こちらを読みなさいと書いてあるドキュメントは、流れがわかるという点では良いのですが、細かな相違点がいろいろ発生しているので注意してください。

プロジェクト設定

CloudKit 対応するためには、プロジェクトの設定も追加する必要があります。

Apple のドキュメントには、こちら を読みなさいと書いてあります。
Xcode 等にもアップデートが入っているので、実際の作業は 説明と少し異なります。

この段階で、"Signing & Capability" で "Automatically manae signing" をチェックしておく必要があります。

Xcode12.3 では、以下の手順となります。

既存の CoreData プロジェクトを CloudKit 対応させるための プロジェクト設定変更の手順です。

  1. CloudKit 対応させるターゲットに、Capability "iCloud" を追加します。
    iCloud capability 追加
    iCloud capability 追加
  2. 追加された "iCloud" capability を設定します。CloudKit をチェックして、+ ボタンをクリックします。
    CloudKit をチェック
    "CloudKit" をチェック
  3. 使用する Container を設定 通常は、iCloud.逆DNS.App名 というようなコンテナ名を使用するようです。
    Container 設定
    Container 設定
  4. Container に設定されていることを確認
    Container設定を確認
    Container設定を確認
  5. "Background Modes" の "Remote notification" を有効化 "iCloud" と同様に、"Background Modes" を追加し、"Remote notifications" を有効にします。
    RemoteNotifications を有効化
    RemoteNotifications を有効化
注意点
  • Apple ドキュメントには、"default container" という表現がありますが、Xcode11 で廃止されたようです。
  • Push Notification は、CloudKit を有効にすると自動で設定されるようです(@Xcode12.3)

上記の操作を行うことで、CloutKit 上に、CoreData で使用するスキーマに相当する CloudKit 側のスキーマを作成してくれます。

CloudKit Dashboard で確認することができます。

Capability の iCloud 設定に表示されていた "CloudKit Dashboard" を押下すると、Web 上での CloudKit Dashboard に移動できます。

CloudKit Dashboard

ログインすると、以下のような画面になります。

CloudKit Dashboard
CloudKit Dashboard

先ほど設定したコンテナが作成されていることが確認できます。

この画面を使って、デバイスで行った変更が iCloud 上に反映されているかを確認することができます。

recordName に Queryable を設定しておくと便利

System Fields の recordName を Queryable 設定にしておくと便利です(recordName で検索できるようにするという意味です)。

以下、その設定方法です。

  1. CloudKit Dashboard 画面で、Schema をクリック
    Schema 設定へ移動
    Schema 設定へ移動
  2. Edit Indexes をクリック
    Edit Indexes をクリック
    Edit Indexes をクリック
  3. Add Index をクリック
    Add Index をクリック
    Add Index をクリック
  4. recordName に QUERYABLE を設定して保存
    recordName に Queryable を設定して保存
    recordName に Queryable を設定して保存

この設定を行なっておくと、RecordName (CoreData での Entity) でデータを検索することができるようになります。

NSPersistentContainer 置き換え

準備ができたので、NSPersistentCloudKitContainer に置き換えていきます。

本当に置き換えるだけです。

TODOItemStore.init

struct TODOItemStore : TODOItemStoreProtocol {
    static let logger = Logger(subsystem: "com.smalldesksoftware.MyTODO.TODOItemStore", category: "TODOItemStore")

    let container: NSPersistentContainer
    
    init(_ inMemory:Bool ) {
//        container = NSPersistentContainer(name: "MyTODO")
        container = NSPersistentCloudKitContainer(name: "MyTODO")
        if inMemory {
            container.persistentStoreDescriptions.first!.url = URL(fileURLWithPath: "/dev/null")
        }
        // .. snip ..

NSPersistentCloudKitContainer は、NSPersistentContainer を継承して定義されていますので、実際にインスタンス化する箇所以外は、変更が不要です。

これだけで、Cloud と同期できるなんて素晴らしいですね。

CloudKit 上で確認

CloudKit 上にスキーマが作成されていることは確認しましたが、いくつかデータを作成して実際に同期させてみましょう。

  • シミュレータで、iCloud アカウント設定を行う
  • シミュレータ上のアプリで、要素をいくつか作成する

iCloud アカウント設定を行わないと、(当然ですが) 同期は行われません。

先ほども使った、"CloudKit Dashboard" に移動して、作成された要素を確認しましょう。

  1. Data へ移動
    Data をクリック
    Data をクリック
  2. Query Records をクリックすると 保存されている Record が表示され、左側の三角を押すと、各レコードの詳細が表示されます。
    QueryRecords で Record を確認
    QueryRecords で Record を確認

こうすることで、デバイスで作成されたデータが、Cloud に 同期されていることが確認できます。

別デバイスで確認

別のシミュレータで アプリを起動してしばらく待つと、データが同期されることを確認できます。

# 別シミュレータでの iCloud 設定を忘れずに

説明は以上です。
不明な点やおかしな点ありましたら、こちらまで。

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です