CoreDataを利用したサンプルアプリ第3段。
前回までにアプリの機能は完成したので、今回はCloudKitを使ってiColudで他端末とデータを連携できるようにしたいと思います。
(例えば、iPhoneで消したデータがiPadでも消え、iPadで追加したデータが自動でiPhoneにも追加されるなど。)
使用するサンプルアプリについてはこちら↓
CoreData+iCloudの事前準備
前提として、プロジェクト開始時に、CoreDataとCloudKitの使用にチェックを入れておきましょう。
後から追加で設定するのは手間です。
AppleDeveroperProgramに加入(有料)
そして、アプリ開発中にCloudkitサービスを利用したり設定画面にアクセスするためには、AppleDeveroperProgramへの加入(有料99ドル/年)が必要とのこと。
ここから、アプリでiCloudを使えるようにするために、いくつか設定が必要です。
プロジェクトファイルにiColudを追加
プロジェクトファイルを選択し、「Signing & Capabilities」タブを開きます。
「+Capabirity」で「iCloud」を検索して追加。
「iCloud」の下の「+」をクリック。
「iCloud.BundleID」でContainers(icloud上のデータテーブル)を作成。
Persistence.swiftファイルにCloudkit用のコードを追加する
準備ができたので、Cloudkitのコードを追加します。
//
// Persistence.swift
// SampleApp
//
// Created by yaguchisato on 2021/11/26.
//
import CoreData
struct PersistenceController {
static let shared = PersistenceController()
static var preview: PersistenceController = {
let result = PersistenceController(inMemory: true)
let viewContext = result.container.viewContext
let newSampleData = SampleData(context: viewContext)
newSampleData.id = UUID()
newSampleData.date = Date()
newSampleData.text = ""
newSampleData.bool = false
newSampleData.image1 = Data.init()
newSampleData.image2 = Data.init()
do {
try viewContext.save()
} catch {
let nsError = error as NSError
fatalError("Unresolved error \(nsError), \(nsError.userInfo)")
}
return result
}()
//ここから変更
let container: NSPersistentCloudKitContainer
init(inMemory: Bool = false) {
container = NSPersistentCloudKitContainer(name: "SampleApp")
if inMemory {
// Enable remote notifications
guard let description = container.persistentStoreDescriptions.first else {
fatalError("###\(#function): Failed to retrieve a persistent store description.")
}
// Persistent Historyのトラッキング有効
description.setOption(true as NSNumber, forKey: NSPersistentHistoryTrackingKey)
// リモートの変更を検知
description.setOption(true as NSNumber, forKey: NSPersistentStoreRemoteChangeNotificationPostOptionKey)
}
container.loadPersistentStores(completionHandler: { (storeDescription, error) in
if let error = error as NSError? {
fatalError("Unresolved error \(error), \(error.userInfo)")
}
})
//データが重複しないよう外部変更はメモリ内を置き換える
container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy
//クラウドからの変更を自動取得して適用する
container.viewContext.automaticallyMergesChangesFromParent = true
do{
try container.viewContext.setQueryGenerationFrom(.current)
}catch { assertionFailure("###\(#function): Failed to pin viewContext to the current generation:\(error)")}
}
}
Appleが掲載してくれているGithubのサンプルコードがとても参考になりました。
プロジェクトファイルからCloudKit DashBordを開く
先ほどプロジェクトファイルに追加したiCloudのcontainersの下にある、「CloudKit Dashbord」ボタンをクリックすると、インターネットブラウザ上で、iCloudのダッシュボード画面(iCloudのデータの管理画面)が開きます。
Xcode上で複数のシュミレーターを起動して、データを追加したり削除すると、デバイス同士で連動するのが確認できます。
(※必ずシュミレーターの設定で、それぞれのデバイスからiCloudにログインしてください。)
ダッシュボード上でも、保存されたデータの確認ができます。
データが何もないと先に進めないので、何かしらサンプルデータを追加する必要があります。
「recordName」を追加する
データをいくつか作ったら、iCloud上にもテーブルができているはずなので、
「Schema」→「Indexes」→「CD_[データ型]」→「Add Basic Index」→「recordName」→「Save Changes」
でrecordNameを追加しましょう。(追加しろって指示が画面上にも出ます。)
本番用に「Deploy」する
データの動きも確認できて、問題ないようだったら、AppStoreに申請する前に、ちゃんと製品として動くよう本番環境用にDeployする必要があります。
deployされていない場合は、ダッシュボードのコンテナ名の下に、”This container has not been deployed to Production”と表示されています。
左下の「Deploy Schema Changes…」からDeployしましょう。
CoreDataとCloudKitでiCloud連携できるアプリ完成
こんな感じで、CoreDataとiCloudを一緒に使えるようになりました。
毎年Appleから新技術が出てきて、CoreDataとCloudKitの連携が簡単にできるようになったのも最近のようですので、この先も進化も楽しみですよね。これでCoreDataを使ったサンプルアプリはおわります。
おつかれさまでした!
↓物足りない方に、続編あります。サンプルアプリに絞込み検索機能をつけましたので、こちらもご参考までにどうぞ。