关于苹果的推送服务,网上的相关资料非常多,最简单的就是组合成一个数组,类似:

$arr['aps'] = array(
'badge'=>1,
'sound'=>'',
'alert'=>'xxx'
);

然后用json_encode处理一下之后,用ssl的方式发送给苹果:

chr(0) . pack("n", 32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack("n", strlen($payload)) . $payload;

$devideToken是设备的token,$payload就是上述的数组json_encode之后的数据。
测试的话是发给:ssl://gateway.sandbox.push.apple.com:2195,正式的话,将sandbox去掉即OK

于是这代码就好写了:

/**
* ApnsService.php
*
* @category
* @package
* @author gouki <gouki.xiao@gmail.com>
* @version 1.0
* @created 2011-10-12-23:45
*/
class ApnsService {
public $token;
public $message;
public $badge = 1;
public $sound;
public $ispad;
public function __construct($token, $message, $badge = null, $sound = null, $ispad = 0) {
$this->token = $token;
$this->message = $message;
$this->badge = $badge;
$this->sound = $sound;
$this->ispad = (int)$ispad;
}
public function send() {
return $this->sendPushInfo();
}
public function sandboxSend() {
return $this->sendPushInfo(true);
}
private function getPayload() {
$body = array();
if ($this->badge) {
$body['aps']['badge'] = $this->badge;
}
if ($this->sound) {
$body['aps']['sound'] = $this->sound;
}
$body['aps']['alert'] = $this->message;
return $body;
}
private function getCertFile() {
return Yii::getPathOfAlias("application") . ($this->ispad ? "/hdDis.pem" : "/iphoneDis.pem");
}
private function getSandboxCertFile() {
return Yii::getPathOfAlias("application") . ($this->ispad ? "/hdDev.pem" : "/iphoneDev.pem");
}
private function getApplePushUrl($isSandbox = false) {
return ($isSandbox == true ? "ssl://gateway.push.apple.com:2195" : "ssl://gateway.sandbox.push.apple.com:2195");
}
private function sendPushInfo($isSandbox = false) {
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert',
($isSandbox == true
? $this->getSandboxCertFile()
: $this->getCertFile())
);
//stream_context_set_option($ctx, 'ssl', 'passphrase', '123456'); //如果设置了密码,这里就不能注释了
$fp = stream_socket_client($this->getApplePushUrl($isSandbox), $err, $errstr, 60, STREAM_CLIENT_CONNECT, $ctx);
if (!$fp) {
print "Failed to connect $err $errstr\n";
return false;
} else {
//print "Connection OK\n";
}
$payload = json_encode($this->getPayload());
//echo strlen($payload); //这里可以精心测试,最大不能超过256个字节即strlen超过256后苹果直接不予处理。
$msg = chr(0) . pack("n", 32) . pack('H*', str_replace(' ', '', $this->token)) . pack("n", strlen($payload)) . $payload;
fwrite($fp, $msg);
fclose($fp);
return true;
}
}

上面的代码非常简单只是作了一个简单的处理和封装。不过有部分路径是基于yii的,所以要改一下就OK了。
主要是自己的记录。