CloudKitを使ってみた Swift版


CloudKitとは、iCloudのデータベースにアクセスするためのライブラリです。Apple標準のアプリ(Mail, Contact, Note, News)で使用しており、複数のデバイスにインストールされたアプリケーションでデータの共有が可能です。(Push通知)
AWSのように、無料枠(Free Tier)と有料枠があります。JavaScript版もあります。

Xcodeから新規にプロジェクトを作成します

Capabilitiesから、iCloudをONにします。CloudKitをチェックします。
(もちろん、iCloudにアクセスするため、AppleIDが必要になります。)
プロジェクトナビゲータに、CloudKitライブラリが追加されます。

CloudKitをインポートします。

CloudTableViewController.swift
import UIKit
import CloudKit

class CloudTableViewController: UITableViewController {

データベースには、パブリックとプライベートの2種類あります。パブリックは誰からも参照できます。書込みはオーナーのみです。
Personsテーブル(3つのString型カラム)に、レコードをインサートしてみます。
key-valueで設定します。(開発環境では、スキーマを前もって作らなくても大丈夫です。)

CloudTableViewController.swift
    // Prepare a record to insert.
    let doc = CKRecord(recordType: "Persons")

    doc["name"] = alert.textFields?.first?.text ?? "no name"
    doc["address"] = "Okinawa Naha"
    doc["tel"] = "080-123-4567"

    // Get a Public DB
    let collection = CKContainer.defaultContainer().publicCloudDatabase
    // Save a record
    collection.saveRecord(doc, completionHandler: { (record:CKRecord?, error:NSError?) in
        if let error = error {
            print("Error occurred: \(error)")
            return
        }
    })

実行します。シミュレータが起動したら、いったん設定画面を開き、iCloudにログインします。再度、実行し直します。

iCloudダッシュボートをSafariで開きます。
https://icloud.developer.apple.com/dashboard/

Default Zoneメニューから、レコードがインサートされたのが確認できます。

次に、プログラムからテーブルの検索をしてみます。
それにはまず、Record Typeから、Personsを選択し、Metadata Indexes >RecordID>Queryをチェックする必要があります。

コードです。NSPredicateで検索条件を指定できます。ここでは、全件検索しています。

CloudTableViewController.swift
    var items = [CKRecord]()

    func loadData() {
        let collection = CKContainer.defaultContainer().publicCloudDatabase
        let query = CKQuery(recordType: "Persons", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))

        // submit a query
        collection.performQuery(query, inZoneWithID: nil) { (records:[CKRecord]?, error:NSError?) in
            if let error = error {
                print("query: \(error)")
            }
            if let records = records {
                self.items = records
                dispatch_async(dispatch_get_main_queue(), { 
                    self.tableView.reloadData()
                })
            }
        }
    }

ダッシュボードから使用状況(アクセスユーザ数、リクエスト数、データ使用量)などをグラフで確認することもできます。

ソート機能

レコードを作成した日時 CreationDateの降順でソートします。
ダッシュボード から、Metadata Indexes > Date Created > Sort をチェックします。
画面右下にあるSaveをクリックして保存します。

コードを下記のように修正します。

CloudTableViewController.swift
    func loadData() {
        let collection = CKContainer.defaultContainer().publicCloudDatabase
        let query = CKQuery(recordType: "Persons", predicate: NSPredicate(format: "TRUEPREDICATE", argumentArray: nil))
        // Sort Persons order by 'creationDate' desc
        query.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]

検索条件の指定

検索条件に使用するPredicateに関しては、下記のページのObjective-Cの説明を参考にします。

カラムnameが、David に完全マッチするレコード

let predicate = NSPredicate(format: "name == %@", "David")

カラムtelが、080で始まるレコード。(tel like '080%')

let predicate = NSPredicate(format: "tel BEGINSWITH %@", "080")

カラムnameが、David or Taylor に完全マッチするレコード

let predicate = NSPredicate(format: "name IN %@", ["David", "Taylor"] )

参考

Brian AdventさんのYouTube
https://www.youtube.com/watch?v=XQ3nLV2778U
https://www.youtube.com/watch?v=BXl5o5_2aEU

CocoaHeadsさんのYouTube
https://www.youtube.com/watch?v=Io94KVQovBk
Apple公式ページ
https://developer.apple.com/library/ios/documentation/DataManagement/Conceptual/CloudKitQuickStart/Introduction/Introduction.html