APNS(Apple Push Notification Services)は書くまでもないと思いますが「プッシュ通知」によりアプリケーション提供側から任意のクライアントにショートメッセージなどでユーザに通知を行う機能です。この機能を使えばアプリ提供者側からの通知はもちろん、ユーザ間のやり取りなど幅広く用いることができます。で、既にこの機能自体がiOS3.0以降で組み込まれているので別段新しい機能、という訳でもないのです。が、一方で多くのユーザにお知らせとしてAPNSを送ろうとすると意外に時間がかかるという・・・・。

あまり知られてはいないようなのですが、APNSを1回のSSLコネクションを通じて複数のユーザ・クライアントに飛ばすことが可能です。APNSで使用されるプロトコルは非常に有名なチュートリアルサイト

How to build an Apple Push Notification provider server (tutorial)で案内されている通りです。複数に送信する場合は、単純にこのメッセージ部を繰り返せばいいようです。プログラム的には以下の感じ。


$devices = (array)$devices;
foreach ($devices as $device) {
  $apnsMessage = chr(0) . 

    // token length
    pack('n', 32) . 

    // device token
    pack('H*', str_replace(' ', '', $deviceToken)) . 

    // payload length
    chr(0) . chr(strlen($payload)) . 

    // payload
    $payload;

  // send apns message
  fwrite($apns, $apnsMessage);
}

但し、注意ごととしては以下の通り。

  • (複数クライアント送信に限ったことではないですが)Payloadが256Byteを超えてはならない
  • 1回の通信で全パケットが約7000Byteを超えるとサーバから切断される、らしい (←どこかで見た・・・)

なので、1メッセージが以下のような最長だとすると・・・・?

  • 1byte – コマンド (token)
  • 4byte – デバイストークン長
  • 32byte – デバイストークン
  • 1byte – コマンド (payload)
  • 1byte – ペイロード長
  • 256byte – ペイロード

295byteとなり、仮にサーバ切断となる7000byteまで達するには20人程なら余裕で許容できる範囲となるはずです。多分、10人程度なら超余裕ではないのかな、と。

APNSに関してはGameCenterやInApp-Purchaseの不具合とは異なってSandboxでも非常に安定をして動きます。なので、リリース(Distribution)前にしっかりと確認を行うことができるのでパフォーマンス調整を行ってみると良いかもしれません。