APNs Provider API(HTTP/2)をPHPで試してみる

  • 42
    いいね
  • 2
    コメント
この記事は最終更新日から1年以上が経過しています。

この記事は?

iOSでPush通知するための新しいAPI(APNs Provider API)が去年の12月から提供されています!

APNs Provider API:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/APNsProviderAPI.html

ソケット通信をするややこしい旧APIとは違い、HTTP/2ベースになって、とってもシンプルに。
送信結果も簡単に取得出来るようになっていいことづくめなので、遅ればせながら、PHP on Mac(OS X El Capitan)で試してみました。

HTTP/2環境整備

まず、PHPでHTTP2のリクエスト実現するには以下の環境が必要です。

  • openssl 1.0.2e以上
  • curl 7.46以上(+nghttp2)
  • PHP 5.5.24以上

opensslインストール

Macにプリインされているopensslのバージョンが古かったので、brewでインストールします。

$ brew install openssl

次にbrewで入れたopensslにリンクを貼ります。

$ brew link openssl --force

バージョン確認して問題なければOK!

$ which openssl
/usr/local/bin/openssl
$ openssl version
OpenSSL 1.0.2f  28 Jan 2016

curlインストール

こちらもプリインされているバージョンが古かったので、brewでインストールします。
nghttp2も一緒にインストール!

$ brew install curl --with-nghttp2 --with-openssl

こちらもリンクを貼るのを忘れないように。

$ brew link curl --force

バージョン確認して以下のような感じになっていればOK!
FeaturesにHTTP2の記載があることを要確認。

$ which curl
/usr/local/bin/curl
$ curl --version
curl 7.47.1 (x86_64-apple-darwin15.0.0) libcurl/7.47.1 OpenSSL/1.0.2f zlib/1.2.5 nghttp2/1.7.1
Protocols: dict file ftp ftps gopher http https imap imaps ldap ldaps pop3 pop3s rtsp smb smbs smtp smtps telnet tftp
Features: IPv6 Largefile NTLM NTLM_WB SSL libz TLS-SRP HTTP2 UnixSockets

PHPインストール

PHPはインストール済の方も多いと思いますが、一回入れ直した方がハマらないかも。

$ brew install --with-homebrew-curl --with-homebrew-openssl  --without-snmp php56
$ brew install php56-mcrypt

phpinfoで確認して、

$ php -r 'phpinfo();'

こんな感じの結果が表示されていればOK!

PHP Version => 5.6.18
(省略)
curl

cURL support => enabled
cURL Information => 7.47.1
(省略)
openssl

OpenSSL support => enabled
OpenSSL Library Version => OpenSSL 1.0.2f  28 Jan 2016
(省略)

PHPスクリプト作成

ここまで来たら楽勝です。

new_api.php
<?php
if(defined('CURL_HTTP_VERSION_2_0')){

    $device_token   = 'your device token';
    $pem_file       = 'path to your pem file';
    // $pem_secret     = 'your pem secret'; // パスワードを設定している場合は必要
    $apns_topic     = 'your apns topic. Can be your app bundle ID';

    $alert = '{"aps":{"alert":"Hello, Nogizaka46","sound":"default"}}';
    $url = "https://api.push.apple.com/3/device/$device_token";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $sample_alert);
    curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array("apns-topic: $apns_topic"));
    curl_setopt($ch, CURLOPT_SSLCERT, $pem_file);
    // curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $pem_secret); // パスワードを設定している場合は必要
    $response = curl_exec($ch);
    $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

    var_dump($response);
    var_dump($httpcode);

    // デバッグ用
    // $info = curl_getinfo($ch);
    // $errno = curl_errno($ch);
    // $error = curl_error($ch);

   // var_dump($info);
    // var_dump($errno);
    // var_dump($error);
}

このPHPをスクリプトを実行して、ステータスコードが200だったらOK!
エラーの場合は、{"reason":"DeviceTokenNotForTopic"}みたいなJSONがレスポンスされます。

感想

HTTP/2に対応した環境をつくるのに少し苦労しましたが、実装やエラーハンドリングが楽になったし、今風のAPIなので、これから積極的に使っていこうと思います。

参考サイト

New APNS Provider API and PHP:
http://stackoverflow.com/questions/34684099/new-apns-provider-api-and-php/34955920
APNs Provider API (HTTP/2 ) を go (1.6) から扱う:
http://soh335.hatenablog.com/entry/2015/12/22/222041
curl エクステンションで HTTP/2 リクエストを送信する:
http://qiita.com/masakielastic/items/f563437c44b0d4c04f87
macのPHPからcURLでhttpsアクセスすると失敗する件:
http://takemaru123.hatenablog.jp/entry/2015/05/22/123753