プッシュ通知のサービスとプロバイダ


なんとなく初投稿です。
AndroidおよびiOSのプッシュ通知の実装を行うことがあり、その際サービスごとの仕様で混乱したので書いておきます。

  • 基本の通知までの流れは
    1. 通知を受ける端末(正確にはインスコされたアプリ)から通知サービスのサーバに端末を登録、端末を識別するトークン(GCMならRegistrationID、APNSならDeviceToken)を取得
    2. トークンを通知を行うプロバイダ()に送信
    3. プロバイダはトークンを使用してサービスのサーバにこの端末に通知送ってくれと依頼

ここまではわかりやすいです。ただテストする上ですこし面倒だったのがアプリとプロバイダとの結びつきです。

アプリとプロバイダとの関係

Androidの場合

Androidでは通知を行う際、GoogleCloudPlatformで作成したプロジェクトの番号をSenderIDとして使用してデバイス登録を行います。これはデバイス登録の関数に引数として渡すだけなので、アプリ起動時にサーバから取得するなど動的に変更するのは比較的容易です。

String senderID = "My-Sender-ID";
String registrationID = GoogleCloudMessaging.getInstance(context).register(SENDER_ID);

つまりアプリをビルドしてパッケージにした段階ではプロバイダへの結びつきが特になく、起動してからプロバイダからもらう情報で結びつけるといったことが可能なです。

iOSの場合

iOSアプリにはプロビジョニングが不可欠ですが、このプロビジョニングがプロバイダのサーバと結びつきます。
プロビジョニングの作成はiOS Developer Centerから行います。プッシュ通知も同様にプロバイダとサービス間で使用するSSL証明書が発行できます。AppIDの設定の編集から行えますがSSL証明書はDevelopmentとProductionの2種類が存在します。

プロビジョニング SSL証明書 サービス(APNS)での環境
Development Development サンドボックス
Distribution Production 本番

なぜかDistributionプロビジョニングに対応するのがProductionになってるのでちょっとわかりにくいですが・・・
どのプロビジョニングでアプリを作ったかですでにプロバイダとの結びつきができていて、Androidのように動的に変更したりは出来ないようになっています。

例えばアプリ(Development)でプロバイダ(Production)に接続した場合
1,アプリがデバイス登録を行い、サンドボックス用のデバイストークンを取得
2,プロバイダはデバイストークンを取得
3,プロバイダはサービスに通知をリクエストするが「無効なトークン」エラーが返される

最後に

プッシュ通知は複数プラットフォームをすべて自前で実装するのは非常に手間ですが、こういう仕様までちゃんと理解していないとあとで困ったことになりそうです。