PHPでスマホアプリに
プッシュ通知する
デジタルサーカス(株)長谷川智希
長谷川智希
とも き
@tomzoh

とむぞう
開発系趣味
その他趣味
Webサイト開発, iOSアプリ開発
レンタルカートレース, 電子工作(mbed), …
TOMZOH
お仕事 スマホアプリ受託開発 Mgr
デジタルサーカス(株) 副団長CTO
Facebook CakePHP iOS
デジタルサーカス(株)
・ Webサイト受託開発
・ スマホアプリ受託開発



・ 自社サービス
(PHP, Drupal, CakePHP)
(iOS, Android)



(http://appbuilder.jp)
Twitter: @tomzoh
Twitter: @tomzoh
Twitter: @tomzoh
今日のテーマ:
PHPでスマホアプリに
プッシュ通知する
今日のテーマ:
PHPでスマホアプリに
プシュッ通知する
今日のテーマ:
PHPでスマホアプリに
プシュッ通知する
🍺
🍺基礎知識🍺
スマホアプリのプッシュ通知
• 呼び方はiOS / Androidでちょっと違う
• iOS: Apple Push Notification Service (APNs)
• Android: Google Cloud Messaging (GCM)
• どっちもHTTPベースの技術でできています😃
• アプリに対して送信します。
• アプリが入っていないと届かない。
プッシュ通知の概要 - 準備
Apple / Google アプリ用サーバ
スマホアプリ
①デバイストークン*1
を取得
*1)AndroidではRegistration ID
プッシュ通知の概要 - 準備
Apple / Google アプリ用サーバ
スマホアプリ
②デバイストークンを登録
(多くのケースではユーザIDや端末IDと
ひもづけて送信する。)
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
プッシュ通知の概要 - 送信
Apple / Google アプリ用サーバ
スマホアプリ
③デバイストークン
とメッセージを送信
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
http
プッシュ通知の概要 - 送信
Apple / Google アプリ用サーバ
スマホアプリ
④プッシュ通知!
お知らせだよ!
でやる
プッシュ通知の概要 - 送信
Apple / Google アプリ用サーバ
スマホアプリ
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
プッシュ通知の概要 - 送信
Apple / Google アプリ用サーバ
スマホアプリ
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
プッシュ通知の概要 - 送信
Apple / Google アプリ用サーバ
スマホアプリ
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
これを で。
Androidのプッシュ通知送信
$ curl 
--header "Authorization: key=【APIキー】" 
--header Content-Type:"application/json"" 
https://android.googleapis.com/gcm/send 
-d "{"registration_ids":["【RegistrationID】"],"data":
{"message":"Hello monotty!"}}"
Androidのプッシュ通知送信
$ curl 
--header "Authorization: key=【APIキー】" 
--header Content-Type:"application/json"" 
https://android.googleapis.com/gcm/send 
-d "{"registration_ids":["【RegistrationID】"],"data":
{"message":"Hello monotty!"}}"
• かんたん。
• 生PHPでもぜんぜんOK。
😇
iOSのプッシュ通知送信
• バイナリインタフェース
iOSのプッシュ通知送信
• バイナリインタフェース
😱• めんどい!
つらたん😭
つらたん😭
• PHPなんだから誰か良いライブラリ作ってくれてる
んじゃないの?😢
つらたん😭
• PHPなんだから誰か良いライブラリ作ってくれてる
んじゃないの?😢
→ 正解。ApnsPHPという鉄板ライブラリがある😊
• composerで入れられるフォークもあり。
• this fork is a Apns_PHP namespaced version!
ideal to use as vendor in sf2 or zf2.
composer
ApnsPHPでのiOSプッシュ送信
ApnsPHPでのiOSプッシュ送信
テスト環境への接続
ApnsPHPでのiOSプッシュ送信
テスト環境への接続
テスト環境用の証明書
基本こんだけ。
簡単。
細かいお話
Apple / Google アプリ用サーバ
スマホアプリ
②デバイストークンを登録
(多くのケースではユーザIDや端末IDと
ひもづけて送信する。)
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
参考1: アプリ用サーバに送信するデータ例
Apple / Google アプリ用サーバ
スマホアプリ
②デバイストークンを登録
(多くのケースではユーザIDや端末IDと
ひもづけて送信する。)
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
参考1: アプリ用サーバに送信するデータ例
{
device_id : 6521e13b9e1e2b45f15b16c65334b622097f07489c96a9a35413b49018b4126a ,
os : iOS ,
device_token : 8994b692542e6d5229fb925fe29a5a60e51017a81eca3d76881c91bf0bce40e3
}
Apple / Google アプリ用サーバ
スマホアプリ
②デバイストークンを登録
(多くのケースではユーザIDや端末IDと
ひもづけて送信する。)
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
参考1: アプリ用サーバに送信するデータ例
{
device_id : 6521e13b9e1e2b45f15b16c65334b622097f07489c96a9a35413b49018b4126a ,
os : iOS ,
device_token : 8994b692542e6d5229fb925fe29a5a60e51017a81eca3d76881c91bf0bce40e3
}
デバイスIDとしてユーザID+シードのハッシュを使うことが多いです。
Apple / Google アプリ用サーバ
スマホアプリ
②デバイストークンを登録
(多くのケースではユーザIDや端末IDと
ひもづけて送信する。)
端末ID1, デバイストークン1
端末ID2, デバイストークン2
端末ID3, デバイストークン3
:
参考1: アプリ用サーバに送信するデータ例
{
device_id : 6521e13b9e1e2b45f15b16c65334b622097f07489c96a9a35413b49018b4126a ,
os : iOS ,
device_token : 8994b692542e6d5229fb925fe29a5a60e51017a81eca3d76881c91bf0bce40e3
}
デバイスIDとしてユーザID+シードのハッシュを使うことが多いです。
iOSの場合こんな長さ(64bytes)。Androidは140∼210bytes程度。
参考2: デバイストークンの変化
• iOSのデバイストークンは変わることがある。
• バックアップからのリストア、OSアップグレード等。
• 起動時に毎回取得してサーバに送信するべき。
• AndroidのRegistration IDも変わることがある。
• こちらも起動時に毎回サーバに送信する。
• どちらも端末IDなどをキーに毎回上書きすることに
なる。
参考3: iOS, 開発 & 本番環境
• iOSの場合、2つの接続先がある。
• 開発ビルド: 開発用プッシュ通知サーバ(SANDBOX)
• リリースビルド: 本番用プッシュ通知サーバ(PRODUCTION)
• デバイストークンが異なる。
• 開発用のトークンを本番に投げるとエラーになる。
• 本番環境に開発用トークンが混ざらないように注意。
• とは言っても混じるので送信プログラム側でエラー処理をちゃ
んとやる。
参考4: 発生するエラー
• iOSの場合、エラーは2パターン。
• 送信時エラー: デバイストークンがおかしい等
• あとからエラー: 電源がずっと入っていないまたは圏外でのタイ
ムアウト、アプリがアンインストールされている等

→ このエラーもApnsPHPで取得できる。(Feedback)
• Androidの場合、送信時エラーのみ。
• Androidではアンインストールを検出できるのでアンインストー
ル時にアプリ用サーバからRegistration IDを削除すべき。
参考5: 多対多?一対多?
• アプリがID/パスワードでログインする場合設計に
注意する必要あり。
• プッシュ通知用のデバイストークンは「端末」に1つ。
• 以下の場合プッシュ通知は「どの端末」に送る?
• ある端末にログイン → ログアウト
• さらにその後別のユーザでログイン
• あるユーザが端末Aと端末Bにログイン
• ある端末にログイン。別の端末にリストア。

余談: iOS, 例のダイアログ
Apple / Google アプリ用サーバ
スマホアプリ
①デバイストークンを
取得
このタイミングで
ダイアログが出る
まとめ
まとめ
• iOSもAndroidも基本的には同じ仕組み。
• デバイストークン / Registration IDを取得。
• 取得したトークンを使って送信先を指定する。
• プッシュ通知送信はHTTPで。
• AndroidはテキストベースのシンプルなHTTP通信で送信できる。
• iOSはちょっと面倒だけど、ApnsPHPを使ってラクできる。
• 特有の要注意ポイントあり。
• APIやバッチ設計時にしっかり考える。
One more thing...
テスト環境用の証明書テスト環境用の証明書
テスト環境用の証明書
証明書の作成
1. MacのキーチェーンアクセスでCSRを作成
2. Apple Developerページにアップロード
3. 証明書をダウンロード
4. Macに証明書をインストール
5. キーチェーンアクセスでファイルに書き出す
6. コマンドラインでpem形式に変換
証明書の作成
1. MacのキーチェーンアクセスでCSRを作成
2. Apple Developerページにアップロード
3. 証明書をダウンロード
4. Macに証明書をインストール
5. キーチェーンアクセスでファイルに書き出す
6. コマンドラインでpem形式に変換
お客さま < Mac無いです!
証明書の作成
1. MacのキーチェーンアクセスでCSRを作成
2. Apple Developerページにアップロード
3. 証明書をダウンロード
4. Macに証明書をインストール
5. キーチェーンアクセスでファイルに書き出す
6. コマンドラインでpem形式に変換
お客さま < Mac無いです!
お客さま < 英語…
証明書の作成
1. MacのキーチェーンアクセスでCSRを作成
2. Apple Developerページにアップロード
3. 証明書をダウンロード
4. Macに証明書をインストール
5. キーチェーンアクセスでファイルに書き出す
6. コマンドラインでpem形式に変換
お客さま < Mac無いです!
お客さま < 英語…
お客さま < 何ですかそれ?
ツール作った
デモ
https://www.monotty.com
ありがとうございました
@tomzoh
デジタルサーカス(株)
声かけてください
おまけ1
エンディアン
• f8a3b2というデータがあった時にメモリにどの様
に格納するか。
f8ビッグエンディアン
+0
a3
+1
リトルエンディアン
b2
+2
f8a3b2
エンディアン
• f8a3b2というデータがあった時にメモリにどの様
に格納するか。
f8ビッグエンディアン
+0
a3
+1
リトルエンディアン
b2
+2
f8a3b2
見た目通り!キモチイイ!
エンディアン
• f8a3b2というデータがあった時にメモリにどの様
に格納するか。
f8ビッグエンディアン
+0
a3
+1
リトルエンディアン
b2
+2
f8a3b2
見た目通り!キモチイイ!
何バイトの値を入れても「1の位」が
最初に来る!キモチイイ!
エンディアン
• f8a3b2というデータがあった時にメモリにどの様
に格納するか。
f8ビッグエンディアン
+0
a3
+1
リトルエンディアン
b2
+2
f8a3b2
見た目通り!キモチイイ!
何バイトの値を入れても「1の位」が
最初に来る!キモチイイ!
エンディアン
• f8a3b2というデータがあった時にメモリにどの様
に格納するか。
f8ビッグエンディアン
+0
a3
+1
リトルエンディアン
b2
+2
f8a3b2
見た目通り!キモチイイ!
何バイトの値を入れても「1の位」が
最初に来る!キモチイイ!
エンディアン
UTF-8のBOM
= Byte Order Mark
= ビッグエンディアンかリトルエンディアンか
エンディアン
UTF-8のBOM
= Byte Order Mark
= ビッグエンディアンかリトルエンディアンか
発表後やさしいマサカリ頂いた。
UTF-8だと関係無い。UTF-16だと関係ある。
@koyhogeさん感謝!!!
エンディアン
おまけ2
PHPでスマホアプリにプッシュ通知する

PHPでスマホアプリにプッシュ通知する