[iOS 8] CloudKit を使ってみよう (4) Push 通知を利用する
CloudKit で Push 通知
これまでレコードの保存や検索などの操作について触れてきましたが、今回は CloudKit の Push 通知機能について解説したいと思います。CloudKit はデータストレージだけではなく、このストレージを活用した Push 通知を実装することができます。何だかとっても mBaaS っぽいですね。
Push 通知を受け取ってみよう
今回は「Memo」という名前の Record Type を対象に、レコードが追加/更新/削除されたら Push 通知を送る機能を実装してみたいと思います。
Remote Notification を有効にする
まずはアプリで Remote Notification を受け取るようにしましょう。基本的にはこれまで通りの方法と一緒ですが、CloudKit を利用している場合は Certificate の登録は不要です。これ結構面倒なので嬉しいですね!
はじめに、プロジェクト設定の Capabilities の Background Modes を有効にし、Remote Notification にチェックします。
次に AppDelegate の application:didFinishLaunchingWithOptions: などで Remote Notification の認証要求処理を実装します。
import UIKit import CloudKit @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? // MARK: AppDelegate func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: NSDictionary?) -> Bool { // Remote Notification の認証要求 var settings = UIUserNotificationSettings( forTypes: UIUserNotificationType.Alert | UIUserNotificationType.Alert | UIUserNotificationType.Alert, categories:nil) application.registerUserNotificationSettings(settings) application.registerForRemoteNotifications() return true } // MARK: Remote Notification func application(application: UIApplication, didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings) { println(__FUNCTION__) } func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { println(__FUNCTION__) println("deviceToken : \(deviceToken)") } func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject], fetchCompletionHandler completionHandler: (UIBackgroundFetchResult) -> Void) { println(__FUNCTION__) } func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) { println(__FUNCTION__) } }
これで実行すると Push 通知の認証アラートが表示されます。認証されると application:didRegisterForRemoteNotificationsWithDeviceToken: が呼び出されます。
Subscription (購読) を登録する
次に Record Type を Subscription (購読) する処理を実装します。ここで Subscription した条件にマッチしたら Push 通知が届くようになります。application:didRegisterForRemoteNotificationsWithDeviceToken: を次のような処理を加えます。
func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) { println(__FUNCTION__) println("deviceToken : \(deviceToken)") // 条件の指定 let predicate = NSPredicate(format: "content == 'Test'") // Subscription の作成 let subscription = CKSubscription(recordType: "Memo", predicate: predicate, options: CKSubscriptionOptions.FiresOnRecordCreation | CKSubscriptionOptions.FiresOnce) subscription.notificationInfo = CKNotificationInfo() subscription.notificationInfo.alertBody = "アイテムが追加されたし" // Subscription の登録 let db = CKContainer.defaultContainer().privateCloudDatabase db.saveSubscription(subscription, completionHandler: { subscription, error in if error != nil { // エラー println("error : \(error)") } else { // 登録完了 println("subscription : \(subscription)") } }) }
まず条件は NSPredicate で指定します。これはレコードの検索でも登場したクラスですね。上記では「content の値が Test の場合」という条件を定義しています。
次に CKSubscription で Subscription を作成します。recordType はレコード名、predicate は上記で作成した NSPredicate オブジェクト、そして options は CKSubscriptionOptions を指定します。CKSubscriptionOptions はレコードのどのような操作を監視するかという設定です。次の中から1つ以上設定します。
値 | 説明 |
---|---|
CKSubscriptionOptions.FiresOnRecordCreation | レコードが追加されたとき |
CKSubscriptionOptions. FiresOnRecordUpdate | レコードが更新されたとき |
CKSubscriptionOptions.FiresOnRecordDeletion | レコードが削除されたとき |
CKSubscriptionOptions.FiresOnce | 1度だけ通知する |
通知されるメッセージは CKNotificationInfo で定義します。次のようなプロパティがセットできます。
値 | 型 | 説明 |
---|---|---|
alertBody | String | メッセージの本文 |
alertLocalizationKey | String | メッセージの本文の Localizable.string のキー |
alertLocalizationArgs | Array | メッセージ本文のフォーマットにセットする値の配列 (NSString, NSNumber, NSDate のいずれか) |
alertActionLocalizationKey | String | Push 通知がアラートで表示されたときのアプリ起動ボタンのテキスト |
alertLaunchImage | String | Push 通知からアプリを起動したときの Launch Image のファイル名 |
soundName | String | 効果音のファイル名 |
shouldBadge | Bool | true にするとバッジの数をインクリメントする |
shouldSendContentAvailable | Bool | true にすると content-available を設定し、Push 通知を受けたときにバックグラウンド処理が実行される |
最後に CKDatabase#saveSubscription を呼び出して終わりです。「content が Test の Memo レコードが追加されたとき」という条件を登録したので、これにマッチするレコードが追加されたときに Push 通知が届くようになります。
実行してみる
それでは実行してみます。Remote Notification を受け取りたいので、アプリがバックグラウンドに居る必要があります。CloudKit Dashboard からレコードを追加してみると、通知が受け取れるはずです。プライベートデータベースを対象にしている場合、追加する側と受け取る側が同じ Apple ID で試してください。
まとめ
サービス系のアプリを作りたいとき、Push 通知を送りたいことはよくあると思いますが、CloduKit だけで利用することができるのでとっても手軽ですね!