この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
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 だけで利用することができるのでとっても手軽ですね!