Google I/O 2015で発表された Google Cloud Messaging(以下GCM)の新機能、Topic Messagingを試してみました。
環境、前提条件などは、先の記事を参照してください。
Topic Messaging とは
Topic Messagingとは、従来のGCMおよびApple Push Notification Service(以下APNs)のような送信先デバイスのトークンを指定してのPush通知ではなく、Publish/subscribeモデルのPush送信を行なう機能です。
Publish/subscribeモデルとは、各デバイスから購読(subscribe)したいトピックをあらかじめ登録することで、メッセージ送信(publish)側では個々のデバイスを意識することなく、トピックに対してメッセージを送ることで購読デバイスすべてにメッセージを配信できるものです。
これによって、例えば、
- ニュースの更新などをPush通知したいだけであれば、サーバアプリケーションでは受信デバイスのRegistration Tokenを管理する必要がない
- 送信機能もクライアントアプリに持たせる場合、サーバアプリケーション自体を立てる必要がない
といった構成が実現できるようになります。
制約・制限
GCMのTopic Messagingには、以下の制約・制限があります。
購読数については、ユーザが1トピックづつ購読して100万ユーザまで、平均2トピックなら50万ユーザまで…となるので、インストール数が見込まれるアプリでは注意が必要です。
トピックの購読
以下、前回同様 Try Google Cloud Messaging for iOS のサンプルを使用して試していきます。
トピックの購読は、次のメソッドで行ないます。(メインスレッドから呼ぶ必要があります)
[GCMPubSub subscribeWithToken:topic:options:handler:]
サンプルのGcmExampleでは、起動時にトピック/topics/global
を購読するようになっています。
トピックへのメッセージの送信
続いて、同じく"Get started"のサンプルプロジェクトにあるGcmServerDemoを起動すると次のウィンドウが表示されます。
apiKey
欄にGCMのAPI Keyを入力し、"Send to topic"ボタンをクリックすると、送信メッセージの(本来、宛先のRegistrationTokenを設定する)to
に、/topics/global
を設定して送信が行われます。
具体的には、以下のメッセージが送られます。
[
"to": "/topics/global",
"notification": [
"body": "Hello from GCM"
]
]
これだけで、トピック/topics/global
を購読しているデバイスすべてにPush通知が送信されます。
トピックメッセージの受信
受信は通常のPush通知と同様です。受信側でトピックメッセージ固有の処理を行いたい場合は、 [UIApplicationDelegate application:didReceiveRemoteNotification:]
メソッドで以下のように判定できます。
-(void)application:(UIApplication)application
didReceiveRemoteNotification:(NSDictionary)notification {
if ([notification[@"from"] hasPrefix:@"/topics/"]) {
// トピックメッセージを受信した
} else {
// 通常のメッセージを受信した
}
}
なお、今のところ、購読されているトピックのリストを取得するようなインタフェースは、サーバ側にもクライアント側にも定義されていないようです。
その他、エラーハンドリングなど詳細は公式のガイドを参照してください。
App nameとBundle ID, Androidアプリとの関連
GCMの利用登録を行なうページでは、"App name"と"iOS Bundle ID"を入力します。ここで、"App name"は、Google Developer Console(API Console)の"Project name"となります。
これに対し、"iOS Bundle ID"は1:nの関係で登録することが可能です。 同様にAndroidアプリ場合、Bundle IDの代わりに"Android package name"欄にパッケージ名(ApplicationID)を登録しますが、これも1:nの関係になります。
トピックメッセージを送信するためのAPI Key、およびSender IDは、"App name"単位に割り当てられます。これに、複数の"iOS Bundle ID", "Android package name"を紐付けられますので、iOS版とAndroid版、また、Lite版やOEMしたアプリなどに対し、一括してトピックメッセージを送信することができます。
なお、iOSアプリ向け設定ファイルであるGoogleService-Info.plist
にはSender IDしか書かれていませんので、複数のビルドターゲットで共有することができます。
Androidアプリ向けのgoogle-services.json
には、Sender IDのほかに登録されたパッケージ名が書かれますが、登録されたパッケージ名が全て配列で書かれるようです。
そのため、フレーバーを定義して複数のアプリをビルドする場合でも、ひとつのgoogle-services.json
を共有して問題ありませんでした。