この記事の内容
サーバーに変数を保存してその内容をアプリがフェッチできるようにしたいと思ったことはありませんか?
- 商品の価格
- 掲載された記事のリスト
- その他...
そんな時にぴったりなのが、CloudKit public databaseです。これはAppleから提供されている無料のサービスで、iOS
、MacOS
、JaveScript Web (CloudKit JS)
環境でのみ利用できます。
CloudKit
について
こちらに私の以前の記事から CloudKit
に関する説明を転載しました。
長所
- データをプライベート・データベース、共有データベース、またはパブリック・データベース(すべてのユーザーが他のユーザーのレコードをフェッチできる)に保存できます。
- CloudKitはAppleの無料クラウドサービスです。
- CloudKitパブリック・データベースへの保存は、割り当て制限に対してカウントされます。
- ユーザーがアプリを削除してから再度インストールすると、CloudKitに保存されているデータをフェッチできます。
短所
- ユーザーはオンラインである必要があります。また、CloudKitデータベースの使用にはサイズ制限があります。
この記事について
この記事では CloudKit
のパブリックなデータベースについて話します。このデータベース上のデータはアプリのユーザー全員がアクセスすることができます。
ユーザーのプライベートな情報を保存したい場合は、CloudKit
のプライベートなデータベースが必要です。詳しくは私の以前の記事をご参照ください
CloudKit
の機能を有効化します。次にコンテナを作成します。
私がここで以前書いた記事のステップ1のセクションをお読みください。
その記事のステップ2のところまで来たらこの記事に戻って下さい。
ステップ2. ユーザー情報を保存するため、CloudKitのデータ構造を設定する。
-
次に"CloudKit Dashboard"ボタンをクリックするか、http://icloud.developer.apple.com へ行く。
-
パネル左側にある自分のアプリケーション名をクリックする。
-
"Schema" をクリックします
"New Type" をクリックします
スキームを追加します
この例では販売する品物とその価格のリストを保存していきます。これが使おうとしているデータスキームです。
名称 | 種別 | 数値例 |
---|---|---|
itemName | String | "ペット小屋" |
itemPrice | Int(64) | 3000 |
Int(64) が保存できる最大値は 2e63 − 1 です。従って Int(64) を使って価格を保存するのなら問題はないものと思われます。
CloudKit
のダッシュボード上にレコードタイプを作成する
-
新規レコードタイプの名称を
Price
としましょう -
作成した新規レコードタイプを選択してください。
Add Field
をクリックして新規のデータフィールドを追加します:
- 上記のフィールドを追加してください。手順が完了すると以下のようになります:
いま作成したレコードタイプをインデクシング(索引化)可能としてください
公開データベースでデータを閲覧するためには、索引化を有効にする必要があります:
Add Indexes
ボタンをクリックしてください
ユーザーの便宜を図るため、ダッシュボードインターフェイスが索引として自動的に recordName
を選択します。青い Save Changes
ボタンをクリックするだけで済みます。
公開データベースで既存のレコードを取得する
上部の Schema
ボタンをクリックし、Data
をクリックしてください

通知: 開発環境を使用しているため、ここで加えた変更は (アプリストアに公開される) プロダクションアプリケーションでアクセス可能ではありません。この記事の後半で、開発からプロダクションにスキームを展開する方法を説明します。また、プロダクション環境で記録を作成する必要があります。
パネルの左側で、データベースを Public Database
に切り替えてください

そして、タイプを先ほど作成したデータベースのタイプに切り替えます。Price
です

このタイプのレコードが現在存在しないことが表示されます。Create New Record
ボタンををクリックして作成してください。

これで、ペット小屋, 3000
のようなサンプルデータを入力することができます。

そして、下部の青い Save
ボタンをクリックし、このレコードを保存します。
さて、再び Query Records
をクリックすると、先ほど作成したレコードが表示されます。

ここで、レコード名(そのデータベースレコードのID)が 31CEB769-8DC1-48FB-69C3-10CFC69C43F6
であることを覚えておいてください。これは後で必要になります。
(追加ステップ) 新たなレコードタイプを作成してアイテムのコレクションを保持する
これは、私たちが今使っている実例の場合に有効な追加ステップです。この場合、あるアイテム列が含まれるようなデータタイプを新たに一つ作成します。これで、アイテムのコレクションを指し示すそのデータベースのレコードのIDをエンコードできます。さらに、弊社のアプリが一般公開された後でも、そのコレクションを後から更新することが可能になります。
コレクションデータタイプの作成:

上記と同じ手順で、このデータタイプにクエリインデックスを追加することも忘れないでください。
コレクション・レコードの作成:
上記のレコードIDを使用して、アイテムのコレクションを含むレコードを作成します。

このレコードの名前は 88F7E1D5-F8C5-5CEC-1253-27937513CB46
であることを覚えておいてください。
アプリでレコードにアクセスする
さて、これらのレコードをiOSアプリで取得します:
レコードをフェッチするには
func fetchItem(itemID: String) {
let db = CKContainer(identifier: "iCloud.com.[アプリiCloudコンテナーの名前]").publicCloudDatabase
let recordID = CKRecord.ID(recordName: itemID)
db.fetch(withRecordID: recordID) { (obtainedRecord, error) in
if let itemName = obtainedRecord?.value(forKey: "itemName") as? String,
let itemPrice = obtainedRecord?.value(forKey: "itemPrice") as? Int64 {
print("Item Name \(itemName) with price \(itemPrice)")
}
}
}
fetchItem(itemID: "31CEB769-8DC1-48FB-69C3-10CFC69C43F6")
を呼び出すと以下の結果が得られます:
Item Name ペット小屋 with price 3000
アイテムのコレクションをフェッチするには
func fetchCollections() {
let appCollectionID = "88F7E1D5-F8C5-5CEC-1253-27937513CB46"
let db = CKContainer(identifier: "iCloud.com.[アプリiCloudコンテナーの名前]").publicCloudDatabase
let recordID = CKRecord.ID(recordName: appCollectionID)
db.fetch(withRecordID: recordID) { (fetchedCollection, error) in
if let itemIDs = fetchedCollection?.value(forKey: "itemRecordIDs") as? [String] {
for itemID in itemIDs {
fetchItem(itemID: itemID)
}
}
}
}
さて、このファンクションを再び実行すると、以下のアウトプットを得ます:
Item Name ぬいぐるみ with price 3500
Item Name ペット小屋 with price 3000
プロダクションにデプロイする
最後にはiCloudの開発用データベースを本番環境にデプロイする必要があります。
通知: 開発環境を使用しているため、ここで加えた変更は (アプリストアに公開される) プロダクションアプリケーションでアクセス可能ではありません。プロダクション環境で記録 (Record) を作成する必要があります。
デバッグのオプション
CloudKit
環境をデバッグする方法はいくつかあります
ライブログ
CloudKit
ダッシュボードで、一番上のドロップダウンメニューをクリックして Log
を選択します
環境の切り替え
シミュレーターでもプロダクション環境への切り替えが可能です。
Core Data
を CloudKit
と使う際にはよい方法ではないかもしれません。Core Data
がローカルの Core Data
のデータベース構造とCloudkit
を同期することを妨げる可能性があるからです。
プロダクション環境を使うには、.entitlement
ファイルを探し、以下のラインを加えます。
<key>com.apple.developer.icloud-container-environment</key>
<string>Production</string>