Adhoc版でプッシュ通知が届かない問題を解決!!
まーたやってもうた。
毎回、テスト配布でAdhoc版のProvisioningを設定して
Releaseモードでアーカイブすると、
そのときに取得したAPNSのtokenと
ストアのリリース版からのAPNStokenがサーバー側で混在してしまって
プッシュが届かないという現象が。。。
これを今回限りでこの現象とはおさらばする!打破!\( ^ヮ゜)>ダハ!
▼まずはこちらを参考に
http://peter78.wordpress.com/2011/04/01/apple-push-notification-service-deployment-tips/
要点は以下。おさらいも兼ねて。
1:Adhoc版=開発環境(≠本番環境)
2:開発環境では本番環境のAPNSを取得することはできない。
3:本番環境(Release版)で取得するAPNSは本番用のもの、
なのでこの本番用APNS tokenが本番用サーバと紐づけられて使用されなきゃだめ。
おまけ:テストで開発版をビルドした端末でストアからリリース落とす場合、
一回アプリを削除してからインストールすること。
つまりは、やっぱり開発環境のAPNS tokenと本番環境のAPNS tokenは絶対混ぜたらあかんで。
ってことらしい。
Adhoc版ってどちらかというと本番環境と同じだ(というか開発環境ではない)と思ってた....
(だってDistributionに紐づけられてるもんね(´・ω・`))
▼仮説
Adhoc版 Provisioningを設定してRelease版でArchiveしたテストアプリを入れた端末は、
AppleのAPNSサーバーに対して本番用のProvisioningでtokenを要求する。
するとAPNSサーバーは
その端末に向けて本番用のtokenを登録してしまう。
そいつは本当は開発環境であるAdhoc版なのに。(悲劇)
そしていざ製品がリリースされて、プッシュ打ちます!
てなったときに、
本当の本番環境で作成されていない登録済みtokenを
端末の本番用tokenとして紐づけてしまうから、
本番サーバーから該当端末に届かなくなるって事なんかな?
でもリリース前テストは限りなく本番に近い環境で行いたいよね。
アーカイブしたもので配布したいよね。
▼解決策を考える
一番簡単そうなのは、
Edit SchemeでArchiveの設定を「Debug」に設定してしまう。
そうしたら登録要求をしてもそれは完全に開発環境版のtokenだから
問題ない気がしたんだよな。
でも、「本番環境になるべく近づけたい」という観点から、
このやり方は結局試すのやめた。
で、思った。
「Adhocモード」っていうのが存在して、
そのときにはAPNSに登録要求自体しない
っていう風にすればいいんじゃない?
例えばマクロ定義しちゃって、
#ifdef文とかでコード自体呼ばれなければいいんよね。
というわけで作戦を開始。
▼STEP1
ということで、以下の方法でまずはAdhocモードなるものを追加!
下のサイトを参考に。
http://qiita.com/uasi/items/79aecac40f1b2a5f929b
このときに、
「Duplicated "Debug" configuration/Duplicated "Release" configuration」
つまり、
「開発環境ベースに作るか本番環境ベースに作るか、どうする?」って聞かれるけど、
私は本番に近い環境にしたかったので本番環境ベースに作った。
「Release Copy」なるものが作られるので、名前を「Adhoc」にする。
で、作ったらPreprocessor Macroに「ADHOC=1(ADHOCですよー)」てマクロを定義する。
▼STEP2
ここまで出来たら、マクロで呼び出し制限をかける!
APNS tokenをAPNSに登録要求するコードはアプリ起動時とかに呼び出すと思うんやけど、
この文を#ifdef文で囲む。
今回は、「Adhoc版じゃなかったら呼んで欲しい」ので、
以下のように。
#ifndef ADHOC
[[UIApplicationsharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge
| UIRemoteNotificationTypeSound
| UIRemoteNotificationTypeAlert)];
#endif
▼STEP3
そして、Edit SchemeからArchive時の設定を「Adhoc」にする。
これでアーカイブするときにAdhoc版でコンパイルされる。
するとAdhoc版では上のコードがスルーされて呼ばれないので
APNSに向けて登録要求がされない=本番環境での混在は起こらない!はず!
ちなみにProvisioningの設定は、
Debug→Development
Adhoc→Adhoc(Distribution)
Release→Distribution
とします。
▼確認
とりあえず本当にマクロがスルーされるのか確認のために
ViewDidLoadでアラート表示のテストをしてみた。
本来ならばReleaseと比較してみたいところやけど無理なので、
Debug(Runでの設定)とAdhoc(Archive)で
BundleIDをかえてそれぞれ挙動をチェック。
これでビルドしてみると...
こちらがDebugビルド こちらがAdhocビルド
できてるう\(^o^)/
というわけでおそらく、これでDebug時とRelease時のみ
APNSの登録要求が呼ばれるはず!
▼注意
今までだとArchive時のデフォルト設定は「Release」になっているけど
テスト配布時には「Adhoc」に変更しているので、
ストアにSubmitするときは必ずこの設定を「Release」に戻してArchiveすること!