iOSのRemote Notificationを試してみた
iOSのRemote Notifiacation(Apple Push Notification service:APNs)を試したので手順をメモっとく。
環境は OSX(Lion)+Xcode4.2
準備しとくこと
大まかには以下。
- iOS 実機でiOSアプリを動作確認できるようにする
- APNs可能なProvisioning Profileを準備する
- プロバイダ(サーバアプリ)に必要な証明書ファイルを準備する
iOS 実機でiOSアプリを動作確認できるようにする
iOSアプリを実機で動作確認しよう-プロビジョニングファイルの作成手順- | クラスメソッド開発ブログ にキレイにまとまってる。
実際にこれと同じことをやった。
ハマったことと言えば、Developer Programを登録する際のAppleIDの名前が日本語だったので、申請途中でペンディングになったこと。
申請とおらないなぁと思いつつしばらく気づかず、数日後に気づいて(名前が????になってた)、
Apple IDの名前を英語表記にしたら、数時間後Apple側で処理再開してくれったぽい。
名前や住所は英語表記に、日本語の住所をiTunesなどで使いたい場合は別アカウントのほうがいいかのかも。
あと、Organizerのサイドバーの"Provisioning Profile"で、"Automatic Device Provisioning"というのをチェックしておくと、
"Use for Development"ボタンを押した際に、自動的に登録される模様。
APNs可能なProvisioning Profileを準備する
上記のProvisioning Profileは汎用的なものなようなので、APNsが利用できない。
なので、新しくProvisioning Profileを作成し、そっちでAPNsできるようにする。
- Provisioning Portal にいく
- サイドバーの"App IDs"からApp IDを作成する
- New App IDボタンから必要事項を入力する
- 証明書を取得し、キーチェーンアクセスに登録する
- Provisioning Profile を作成
- ProvisioningPortal でサイドバーのProvisioningを選択
- "New Profile"ボタンから必要事項を入力
- App IDは上で作ったものにする
- 画面リフレッシュすると一覧に追加されているのでDL
- Provisioning Profileを登録
- Xcode の Organizer を開く
- Devicesタブを選択し、サイドバーのProvisioning Profilesを選択
- DLしたProvisioning Profileファイルをドラッグアンドドロップ
プロバイダ(サーバアプリ)に必要な証明書ファイルを準備する
Macのキーチェーンアクセスとopensslで証明書を作成する
- キーチェーンアプリを起動
- 自分の証明書を秘密鍵を選択状態にする
- 左上のキーチェーンを"ログイン"、左下の分類を"自分の証明書"から行くと、証明書と秘密鍵が階層になっているのでこの2つを選択
- メニューバーの[ファイル] - [書き出す] を選択
- フォーマット".p12"形式で書きだす
- パスワードを何か決めて入れる
- フォーマット".p12"形式で書きだす
- 以下のコマンドで"pem"形式に変換
- openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes
- パスワード聞かれるので".p12"形式で書きだした際のパスワードを入れる
- openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes
CertificateName.pem をプロバイダが使用してAPNsにアクセスする。
また、このやりかただと接続する際にパスフレーズは不要だった。
プロバイダでやんないといけないこと
大まかには以下。
- iOSからデバイストークンを受け取る
- プロバイダからAPNsに通知したい情報を送信する
- 通知したいデバイスのデバイストークンも渡す
- APNsとはSSL通信するので証明書が必要。(このへんの準備の理解があやしい)
- APNsからプロバイダへのフィードバックを受け取れるようにする
- (iOSアプリのアンインストールなどで)通知に失敗した場合など、APNsからフィードバックされる
プロバイダ側も色々あるが、今回はiOSで通知を受け取るのに必要最低限なところだけ書く。
動作確認用に、Apple Push Notification Services Tutorial: Part 1/2 にあるPHPのサンプルをプロバイダとして利用した。
なので、以下を行った。
- iOSからデバイストークン受け取る代わりに、iOSのデバッグログからコピってコードに直接書く
- APNsからのフィードバックはやんない
- 先ほど準備した証明書を"ck.pem"という名前でPHPサンプル(simplepush.php)と同フォルダに置く
で、実行すると
$ php simplepush.php Connected to APNS Message successfully delivered
といった感じで成功した。
iOSアプリでやんないといけないこと
大まかには以下。
- iOSに対してAPNsにデバイストークンを登録するための依頼をする処理を書く
- iOSからデバイストークンを受け取ったときの処理を書く
- iOSからデバイストークンを受け取れなかったときの処理を書く
- APNsから通知を受けたときの処理を書く
以下のようなコードをApplicationDelegate.mに追記。
今回はiPod touch(4th)+iOS 5.0.1 で試し、通知を受け取ることができた。
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //画面起動時の初期化がここで行われる //以下を追加。通知を受けたい種別を引数に渡す registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert)]; return YES; } //デバイストークン取得に成功した場合呼ばれる - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken { NSLog(@"Registration Successed. token: %@", devToken); //ここでプロバイダにデバイストークンを送信すべし } //デバイストークン取れなかった場合(シミュレータの場合ここにきた) - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)err { NSLog(@"Error in registration. Error: %@", err); } //通知センタや通知ダイアログから起動すると呼ばれる //アプリがforegroundの場合もこれが呼ばれた - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { NSLog(@"ReceiveRemoteNotification on foreground: %@", userInfo); }
もっと他にも色々ありそうだけど、とりあえずここまで。