Takahiro Octopress Blog

-1から始める情弱プログラミング

はっきりさせよう!iOSのデバイストークン

iOSのデバイストークンを理解しよう!

今回はプッシュ通知をユーザに送る機能を備えたiPhoneアプリを開発したことがあるエンジニアであれば周知の事実であろう『iOSのデバイストークン』について改めて勉強したいと思います。
筆者は正直、今日まで全くの勘違いをしていました…。デバイストークンとはアプリ毎に異なるのだと思い込んでいたのです。

公式ドキュメントを読もう!

まずは何と言ってもAppleの公式ドキュメントから理解してみよう!ということです。
ドキュメントには『APNsが初めてデバイスに接続したときに、APNsからそのデバイスに渡される不透過なデバイス識別子です。(たとえて言えば、デバイストークンは通知先を識別するための電話番号と同じ機能を果たします)』とあります。ここからわかることはデバイストークンとは個人を特定できるユニークなものだということです。
次に読み進めていくと、『APNsは、TLSのピアツーピア認証を利用して、接続してきたデバイスの認証を行います』、『プロバイダとAPNs間の接続信頼も、TLSのピアツーピア認証を利用して確立されます。』と書かれています。何だかふ〜んと言った感じで読み飛ばしてしまいそうですが、実はここは結構重要でした。 このTLS接続は『一意の秘密鍵と証明書を使用してサービスへの認証を行う』ことで確立させます。
最低限ここまで抜粋できれば良しとしましょう笑

実際に取得してみた結果は?

百聞は一見にしかずということで、実際に自分の目で確かめてみることにしました。

手順は省き、結果を言うと『デバイストークンは端末ごとにユニークなもの』です。

アプリごとにユニークではない、1端末につき1つのデバイストークンということがポイントです!
それではアプリAにプッシュを送ろうとすると、アプリBにプッシュが届くのではないか?と思うかもしれません。私も昨日まで完全にそう思っていました。が、ここで先ほど述べた

一意の秘密鍵と証明書を使用してサービスへの認証を行うことでTLS接続を確立する

が意味を成すのです。
そう、秘密鍵と証明書を使用してTLS接続を確立している時点でアプリAへの依頼なのかアプリBへの依頼なのか決まっているのです。

因みに…

因みに、そもそも私がデバイストークンとは端末のアプリごとに異なると思っていた理由を紹介しましょう。
先ほどの説明の中でデバイストークンは1端末につき1つのデバイストークンと言いましたが、それをいきなり覆します!
実はDevelopment版とProduction版でデバイストークンは異なるんです!
これに私は完全に翻弄されてしまったのです(汗)
そして、プッシュの証明書が異なれば(つまりはアプリごと)デバイストークンは異なるのだと思いこんでしまったのです…。

ではなぜDevelopment版とProduction版でデバイストークンは異なるのでしょうか?完全なる答えはわかりませんが、
Development版はプロバイダアプリケーションの初版の開発とテストに使用されるサンドボックス環境であり、アクセス先として『gateway.sandbox.push.apple.com』を設定します。
一方でProduction版のアクセス先はsandboxを外した『gateway.push.apple.com』を設定します。
なるほど、アクセス先が違うのでデバイストークンが変わりそうな気がします…
参考までにサイトのページを載せておきます。
Apple Developer サイト

ここまで説明した内容は全てiOS6.1以前のものであり、iOS7は含みません。iOS7からはアプリごとに異なるといった記事も見られるので、またのちほど実験していくつもりです。

皆さんもぜひ自分の眼でお試しあれ
しかし、今回は全部、文字になってしまったな〜。気が向いたらもう少しわかりやすく編集し直します。

Comments