iPhoneのPush通知「APNS」をphpから完璧に通知させる方法
iphoneアプリをつくると必ずといっていいほど欲しいプッシュ通知。
iphoneの場合、APNSというものがPush通知のシステムとなります。
Apple Push Notificationを理屈抜きにとりあえず実装
ものすごーく簡単に説明するとAppleの通知センターに通知内容とともに、端末のデバイストークンを付加し送信することで、
該当の端末に通知が送られるというもの。(デバイストークンの取得方法は今回は記述しません)
こちらの記事が参考になりそう⇒Apple Push Notification サービス(APNs) の実装方法
今回はデバイストークンを取得してから実際に通知を送るプログラムをPHPにて紹介いたします。
実際のソースコードはコチラ↓
[php]
//============================================
// class_apns.php
//============================================
// 接続先
define(‘C_APNS_SOCKET’,’ssl://gateway.sandbox.push.apple.com:2195′);
define(‘C_APNS_MESSAGE_SIZE’,256);
//+++++++++++++++++++++++++++++
// class_apns
//+++++++++++++++++++++++++++++
class class_apns{
// 接続用PEMのパス
var $APNS_PATH = “”;
// Put your private key’s passphrase here:
var $APNS_PASSWORD = ”;
// APS設定情報(必要なものを記述)
var $APNS_BODY = array(
//’alert’ => $message,
//”badge” => 1,
//’sound’ => ‘default’,
//’content-available’ => 1 // バックグラウンド起動
);
// 送信先デバイス
var $APNS_DEVICE_TOKEN = array();
// 初期化
function init($path,$password){
$this->APNS_PATH = $path;
$this->APNS_PASSWORD = $password;
return true;
}
function setBody($body){
$this->APNS_BODY = $body;
return $this->APNS_BODY;
}
function setDeviceToken($token){
$this->APNS_DEVICE_TOKEN = $token;
return $this->APNS_DEVICE_TOKEN;
}
// APNS 接続
function connectAPNS($sslclient,$pem_path,$passphrase,$retry=false){
$ctx = stream_context_create();
stream_context_set_option($ctx, ‘ssl’, ‘local_cert’, $pem_path);
stream_context_set_option($ctx, ‘ssl’, ‘passphrase’, $passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client($sslclient, $err,$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp){
// 接続エラーになったので1秒後再接続を試みます
if($retry){
sleep(1);
return $this->connectAPNS($sslclient,$pem_path,$passphrase);
}
}
return $fp;
}
// メッセージサイズの取得
function getMessageSize($deviceToken){
// Create the payload body
$body = array();
$body[‘aps’] = $this->APNS_BODY;
// Encode the payload as JSON
$payload = json_encode($body);
$msg = $this->getMessage($deviceToken,$payload);
return strlen($msg);
}
// メッセージ取得
function getMessage($deviceToken,$payload){
return chr(0) . pack(‘n’, 32) . pack(‘H*’, $deviceToken) . pack(‘n’, strlen($payload)) . $payload;
}
// Push通知
function pushMessage(){
$fp = $this->connectAPNS(C_APNS_SOCKET,$this->APNS_PATH,$this->APNS_PASSWORD,true);
if(!$fp){
//exit(“Failed to connect”.PHP_EOL);
return false;
}
$result_list = null;
// Create the payload body
$body = array();
$body[‘aps’] = $this->APNS_BODY;
// Encode the payload as JSON
$payload = json_encode($body);
$size = 0;
foreach ($this->APNS_DEVICE_TOKEN as $deviceToken){
$msg = $this->getMessage($deviceToken,$payload);
$msg_size = strlen($msg);
$result = fwrite($fp, $msg, $msg_size);
// 接続成功
if($result){
$result_list[] = $result;
}
$size += $msg_size;
// 1回の通信で全パケットが5000?7000バイトを超えるとAPNSから切断されるので再接続
if($size >= 5120){
fclose($fp);
sleep(1);
$fp = $this->connectAPNS(C_APNS_SOCKET,$this->APNS_PATH,$this->APNS_PASSWORD,true);
$size = 0;
}
}
fclose($fp);
return $result_list;
}
}
[/php]
実際の使い方とAPNSの注意点
APNS用のクラスを作成してあるので、
$apns = new class_apns();
$apns->init($path,$password);
// デバッグ設定
$apns->setDebug(false);
$options = array(
”alert” => “メッセージが入ります。”,
“badge” => 4, // バッチ数
“sound” => “default”, // 音を出すか
“forgrand” => 0,
“content-available” => 1,
);
// 送信先の設定
$apns->setDeviceToken($tokenlist);
//送信
$result = $apns->pushMessage();
と致します。
$path ・・・ 「.pem」ファイルへのパス。Macで作成することができるが今回は割愛。
$password・・・認証パスワード
この辺は少しAPNSがどういったものかを調べればつくれるかと思います。
自分でつくっておいて、中身はすっかり忘れているのですが、とりあえず動作的には問題ありません。
メッセージだけを送る、音を鳴らす(バイブを鳴らす)、バッチ数のみといった使い分けもできるので便利かと。
APNSは公式にはっていませんが、なぜか256バイト以上を一度に送信しようとすると切断されるそうです。
その辺も対応済みなので、バリバリ動作いたします。
※ただし、通知を1通1通送っているので100~の通知はものすごくサーバーに負荷がかかります。
ほんとは一度に通知を送るほうも実装したいけど・・・・次の機会にw
もしよかったら使って下さいm(_ _)m