Submitted by gouki on 2012, April 17, 9:37 AM
原文地址:http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW1
供应商与苹果推送通知服务器的沟通
翻译:tangly
供应商与苹果推送信息服务器通信
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingWIthAPS/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW1
普通供应商的需求
作为一个供应商与苹果推送通知服务的通信。这个接口对于程序供应商是高速的、大容量的接口;它使用一个流TCP插座设计结合二进制的内容。二进制接口是异步的。
生产环境的二进制接口可以通过gateway.push.apple.com端口2195来连接;沙箱(发展)环境的二进制接口可以通过gateway.sandbox.push.apple.com端口2195来连接。您可能会建立多个并行连接到相同的网关或多个网关的实例。
对于每一个接口可以你应该使用TLS(或SSL),以建立一个安全通信通道。这些连接所需的SSL证书通过IOS服务器分配。 (细节见“配置和发展”。)要建立一个值得信赖可以供应商的身份,在连接的时候,你应该使用此证书点对点的验证连接到APNS
注:建立一个TLS与APNS的会话,委托安全的CA根证书必须安装提供商的服务器上。如果服务器是运行Mac OS X,这根证书已经在钥匙串中了。在其他系统中,证书可能无法使用。你可以下载来自委托SSL证书的网站的证书。
你也应该保留与APNs连接的多个通知。APNs可能会考虑,迅速,并多次作为一个拒绝服务攻击可以建立和撕裂可以连接。错误时,APNS会关闭发生错误连接。
你作为一个供应商,应该以下几个方面的推送通知负责:
l 您必须构建有效的通知(见“有效通知”)。
l 你必须负责提供标志(badge)号在应用程序图标上显示(右上角)。
l 您应该定期与反馈Web服务器连接,并获取目前那些已经多次报道过失败的传输的设备列表(清单)。然后,你应该停止向这些应用程序相关联的设备发送通知。更多信息可以见“反馈”服务。
如果您打算支持多种语言的通知消息,但不使用客户端获取的本地化提醒字符串APS有效载荷字典LOC键和LOC - ARGS属性,你需要本地化警报消息可以文本服务器端。要做到这一点,你需要找出目前的客户端应用程序的语言偏好。 “调度,登记,处理通知”可以说明为获得这一信息的方法。 LOC键和LOC- args的属性信息可以请可以“通知有效载荷”。
二进制接口和通知格式
二进制接口采用的二进制内容的信息流在本质上是一个普通的TCP套接字。为了获得最佳性能,你应该在单一的传输接口通过分批传输多个通知,明示或使用一个TCP / IP Nagle算法。
该接口支持两种格式的通知数据包,简单的格式和增强的格式,以解决一些简单的格式的问题:
l 通知的有效期:APNS有一个存储并转发的功能,它可以保证最近的通知发送到装有应用程序的设备上。如果该设备是在接收通知时掉线,当该设备下次联网时,APNS会再次提供通知。简单的格式,不管通知是否是已经发送过针对性的通知。换句话说,该通知可以随着时间的推移变得“过时”。增强的格式包含着一个有限期值来表示通知有效期。当通知期限值到时,APNS会丢弃存储和转发器里的通知。
l 错误的反馈回应:简单的格式,如果你发送一个通知数据包,在某种方面是畸形的,例如,发送的内容超过规定的限制, APNS会响应切断连接,而且它不会给明拒绝通知的原因。增强的格式,让一个供应商用一个任意的标识符来标记通知。如果有一个错误,APNS会返回一个与该错误代码相关联的标示符。这种应答使供应商能够查找和纠正畸形的通知。
大多数供应商推荐使用增强的格式。
让我们研究简单的通知格式,首先是因为这种格式被增强格式所共享。图5-1说明了这种格式。
Figure 5-1 Simple notification format
图5-1 简单通知格式
简单的格式中的第一个字节是0(零)的命令值。设备令牌和发送消息的长度必须是在网络字节序(即大端法)。此外,您应该使用二进制格式对设备令牌进行编码。发送的消息内容不得超过256字节,不得是null结尾的。
清单5-1给出了一个函数使用简单的通知格式发送一个推送通知 到APNS上的二进制接口的例子。该示例假定SSL优先连接gateway.push.apple.com(或gateway.sandbox..push.apple.com)和对等交换认证。 请看官网代码
清单5-1使用简单格式发送通知到二进制接口
图5-2描述了通知数据包的增强格式。这种格式,如果APNS上的遇到无法理解的命令,它会在断开连接之前返回一个错误应答。
图5-2 增强通知格式
增强通知格式的第一个字节是为1的命令值。这种格式中的两个新字段是标识符和通知的有效期。(其它的都和简单的通知格式相同。)
l 标识符----一个任意值用来标识此通知。如果是APNS无法理解的通知,则返回一个错误应答包,包含此标示符。
l 有效期----一个固定的UNIX纪元日期(UTC)以秒为单位标识通知不再有效,并且可以被丢弃的时候。有效期值应该是网络顺序(大端法)。如果有效期值为正数,APNS至少试图提供一次通知。您可以指定零或一个小于零的值请求APNS不存储通知。
如果你发送的通知在APNS上发现通知格式不完整或其他无法解析的,它会在断开之前返回一个错误应答数据包。(如果没有错误,APNS不返回任何内容。)
图5-3给出了错误应答数据包的格式。
图5-3 错误应答数据包格式
该数据包包含一个值为8的命令值,紧跟一个字节的状态代码,和一个供应商指定的通知相同的标示符。表5-1列出了可能的状态代码及其含义。
Invalid :无效的
表5-1 错误应答的编码
状态代码
|
表示
|
0
|
No errors encountered
|
1
|
Processing error
|
2
|
Missing device token
|
3
|
Missing topic
|
4
|
Missing payload
|
5
|
Invalid token size
|
6
|
Invalid topic size
|
7
|
Invalid payload size
|
8
|
Invalid token
|
255
|
None (unknown)
|
清单5-2修改清单5-1的代码然后构成增强格式的推送通知将其发送到APNS。依然假定SSL优先连接gateway.push.apple.com(或gateway.sandbox..push.apple.com)和对等交换认证。
清单5-2使用增强格式发送通知到二进制接口
注意,生产环境的设备令牌和发展环境(沙箱)的设备令牌是不一样的值。
------
最后一句很重要啊。否则会出问题。
不过,我在苹果服务器反馈服务提到的只是普通的令牌而不是加强型的
上述原文:http://hi.baidu.com/tangly888/blog/item/183a0e88432eb7c8fc1f106b.html
Tags: 推送
苹果相关 | 评论:0
| 阅读:17198
Submitted by gouki on 2012, April 17, 9:28 AM
如果供应商试图发送推送通知到一个应用程序,但应用程序已经不存在该设备中了,设备会报告一个信息给苹果推送通知服务器。这种情况经常发生,当用户卸载应用程序后。如果设备报告了尝试传递应用程序推送通知时的失败,APNS需要一些方法来通知供应商,以便它能够避免再次将通知发送到该设备。这样做可以降低不必要的消息开销和提高系统的整体性能。
为此苹果的推送通知服务器包括一个反馈服务,APNS不断更新每个应用程序的失效的设备令牌列表。该设备是识别设备令牌是否由二进制格式的编码的。供应商应定期查询反馈服务来获取他们的应用程序的设备令牌,以鉴别是否还存在(名单)。然后,验证应用程序是不是最近(被识别的设备)重新注册了,否者供应商应停止向这些设备发送通知。
反馈服务可以通过一个二进制接口来访问,和发送推送通知相类似。您可以通过feedback.push.apple.com端口2196访问反馈服务的结果; 您可以通过feedback.sandbox.push.apple.com端口2196访问沙盒的反馈服务的结果。至于二进制接口与推送通知一样,您必须使用TLS(或SSL)来建立一个安全的通信通道。这些连接所需的SSL证书是同一个是发送通知提供的。要建立一个值得信赖可以供应商的身份,你应该与APNS使用点对点的连接验证时提交此证书。
一旦连接,传输立即开始,你不需要发送任何命令到APN。开始读取反馈服务传输过来的数据流,直到没有数据流了。数据是具有以下格式的元组:
图5-4 反馈元组的二进制格式
Timestamp
A timestamp (as a four-byte time_t value) indicating when the APNs determined that the application no longer exists on the device. This value, which is in network order, represents the seconds since 1970, anchored to UTC.
You should use the timestamp to determine if the application on the device re-registered with your service since the moment the device token was recorded on the feedback service. If it hasn’t, you should cease sending push notifications to the device.
Token length
The length of the device token as a two-byte integer value in network order. 设备令牌的长度为两个字节的整数值的网络字节序。
Device token
The device token in binary format.
Tags: apple, 反馈
苹果相关 | 评论:0
| 阅读:20200
Submitted by gouki on 2012, April 17, 9:26 AM
来源:http://hi.baidu.com/tangly888/blog/item/62948520121870559358074f.html
翻译苹果文档 地址: 翻译:tangly
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW9
推送通知消息负载内容
每个推送通知都带有内容负载,这个负载内容会被应用程序下载并提醒用户收到数据。负载内容最大允许为256个字节,苹果推送通知服务器拒绝任何超过最大负载字节的推送通知。记住,通知的提交是“尽力而为”,它并不能得到保证。
对于每一个通知,供应商组成一个JSON自动对象来严格遵守RFC 4627协议,这个字典必须通过aps键来包含另一个字典的标示,aps键包含一个或多个属性,指定以下操作:
1. 向用户显示一个提示消息
2. 应用程序图标上的一个徽章号码
3. 可播放的声音
警告: 警告你可以将提示消息,徽章图标号码,播放声音结合成一个单一的通知消息,你应该考虑到推送通知的人机界面问题,例如,用户可能受到频繁的提示消息和警告声音,这然人烦。
当通知到达时,如果这时候目标程序没有运行,这提示消息,声音,徽章号码会被播放或被显示;如果应用程序正在运行,ios将它作为一个NSDictionary对象提供给应用程序委托,这个字典收录了相应COcoa属性列表中的对象
供应商可以指定评估命名以外的消息内容,自定义消息负载内容,自定义值必须使用Json结构和基本类型:字典(对象),数组,字符串,数字,boolean。作为定制消息数据,你不应该包含用户的一些信息。相反,为设置上下文(用户界面)或内部指标为目的来使用它。例如,当供应商发送通知的时候,一个自定义通知消息可能会成为一个会话标示符被消息客户端应用或时间戳确认来使用。提示消息的任何行为都不应该具有破坏性,如删除客户设备上的数据
关键:由于传送不能够被保证,所以你不应该依赖远程通知设施提供有效负载消息内容给应用程序,不要再消息负载内容中带有敏感数据,你使用它仅是告诉用户此应用有新的数据可用了
表3-1中列出了有关苹果服务器消息负载内容的键和预期值
Key
|
类型
|
Comment
|
alert
|
字符串或字典
|
如果包含这个这个属性 iOS 将会显示一个标准的提示. 你可用指定一个字符串作为提醒或作为字典的值. 如果你指定了一个字符串, 它会变成有两个按钮的警报消息: 关闭和显示. 如果用户点击查看, 应用程序将会启动
另外, 你可以指定一个字典来作为提示的内容. 对于这类字典,请查看表3-2
|
badge
|
数字
|
这个数字将作为应用程序的的徽章图标显示. 如果此属性不存在, 任何当前显示的徽章号码将会被删除
|
sound
|
字符串
|
它是捆绑再应用程序的声音文件名. 这个声音文件播放声音警报. 如果这个声音文件不存在或指定默认值,这时会播放预设的警报音. 它的音频必须是兼容的系统数据格式之一; 详细信息,请阅读“”准备定义提示音
|
表3-1 alert属性的子属性
Key
|
Value type
|
Comment
|
body
|
string
|
The text of the alert message.
|
action-loc-key
|
字符串或空
|
如果字符串是指定的, 将显示带有两个按钮的警报, 其行为请看表3-1. 然而, ios 用字符串作为键来获得当前本地化的字符串,并将其用于右边按钮的标题,代替了“view”. 如果字符串值为null,系统将显示一个简单的“确定”按钮,当点击时,将会简单的消除按钮. 看 “Localized Formatted Strings” 获得更多消息
|
loc-key
|
字符串
|
本地提示消息的一个字符串钥匙, 字符串钥匙可以格式化这样%@ and %n$ 在loc-args指定参数变量. 看 “Localized Formatted Strings” 可以获得更多信息.
|
loc-args
|
字符串数组
|
变量的字符串值格式化再loc-key出现. 看 “Localized Formatted Strings” 可以获得更多信息 .
|
launch-image
|
字符串
|
图形文件名在应用程序中已经绑定; 它可能包括扩展或省略. 当用户点击动作按钮或移动动作滑块,图片将会被显示出来. I如果这个属性没有指定, 系统会使用以前的图片,通过在应用程序的Info.plist键来使用图像识别, 或返回到默认的png文件
这个属性再ios4.0才被添加的
|
注意:如果你想要iphone,ipad,ipod touch设备将一个通知作为消息文本来显示,那就的有关闭和显示两个按钮
Tags: 推送, budge, json
苹果相关 | 评论:0
| 阅读:19315
Submitted by gouki on 2012, April 17, 9:18 AM
昨天晚上在查资料的时候,发现这个博客,上面的四篇文章不错,我一一转过来先。
来源:http://hi.baidu.com/tangly888/blog/item/9c85cfaaae68e9e71f17a249.html
地址:翻译:tangly
http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ApplePushService/ApplePushService.html#//apple_ref/doc/uid/TP40008194-CH100-SW9
本地格式字符串
你可以用两种方式来显示本地提示信息,通知服务器的本地化文本;要做到这一点,它必须发现当前设备的语言偏好,或者客户端应用程序可以存储器绑定的提示消息字符串并支持将其翻译成本地化语言。供应商再通知负载的aps字典里面指定了loc-key和loc-args属性,当设备接收到通知(应用程序没有运行)
他使用这些APS字典的属性来查找和使用本地化字符串来格式化当前消息,然后再显示给用户
这里介绍第二种
一个IOS应用可以支持国际化资源,如图像,声音,文字的每一种语言的表示,国际通用化这些资源,然后将其分成两部分捆绑再一个子目录中:语言代码和.lproj后缀格式的扩展(如fr.lpor),编程显示本地化的字符串放在一个文件名为Localizable.strings的文件中,在这个文件中的每个条目有一个键和一个本地化的字符串值在这个文件中的每个条目有一个键和一个本地化的字符串值,
字符串值可以有格式说明符来进行替代。当一个应用程序要求一个特定资源,说一个本地化的字符串,它得到的是当前用户选择的语言本地化的资源
例如,首选语言是法语,相应的提升消息字符串值将到应用程序目录的fr.lproj中获取Localizable.strings(IOS通过NSLocalizedString的宏来实现这种要求)
注意:当action-loc-key属性是个字符串,一般都是如此,这个字符串是一个本地化目录Localizable.strings当前选定的语言的关键,ios使用这个键来获得提示消息按钮中右边按钮的标题(“action”按钮)
为了更清楚,我们来举个例子,供应商指定了以下指定了以下字典作为alert属性的值
"alert" : { "loc-key" : "GAME_PLAY_REQUEST_FORMAT", "loc-args" : [ "Jenna", "Frank"] }
当用户收到通知消息,它使用"GAME_PLAY_REQUEST_FORMAT"作为键在Localizable.strings文件的.lproj字典中查找相关的字符串值作为当前语言的值,
假设当前本地中有个Localizable.strings,如下:
"GAME_PLAY_REQUEST_FORMAT" = "%@ and %@ have invited you to play Monopoly";
设备会显示这样一条提示信息:“Jenna and Frank have inveited you to play Monopoly”
除了使用格式符号%@,你可以再字符变量值的位置用“%n$@"代替,n代表了loc-args的下标(从1开始)(这也可以用两个%%符号来表示一个百分号标记(%))
所有如果在localizable.strings条目如下:
"GAME_PLAY_REQUEST_FORMAT" = "%2$@ and %1$@ have invited you to play Monopoly";
设备就回显示这样一条提示信息:”Frank and Jenna have invited you to play monopoly“
对于通知消息负载使用的loc-key和loc-arg属性的完整列子,请看下一个列子“Examples of JSON payloads”,为了学习更多关于ios国际通用化的知识,请看““Build-Time Configuration Details”” in iOS Application Programming Guide,对于国际通用化的一般信息,请看 Internationalization Programming Topics
JSON例子
下面通知有效负载内容的例子说明了表3-1中的属性再实际应用中的使用
带有“acm”属性的键是用户自定的负载内容。这些例子包含了空格和换行来提高可读性,为了更好的执行,供应商应该删除这些空格和换行
例子自己看去
膘叔:骗子啊,最后一段哪有例子。。。
苹果相关 | 评论:0
| 阅读:15635
Submitted by gouki on 2012, April 17, 9:11 AM
关于苹果的推送服务,网上的相关资料非常多,最简单的就是组合成一个数组,类似:
XML/HTML代码
- $arr['aps'] = array(
- 'badge'=>1,
- 'sound'=>'',
- 'alert'=>'xxx'
- );
然后用json_encode处理一下之后,用ssl的方式发送给苹果:
XML/HTML代码
- 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
于是这代码就好写了:
PHP代码
-
-
-
-
-
-
-
-
-
- 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())
- );
-
- $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 {
-
- }
- $payload = json_encode($this->getPayload());
-
- $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了。
主要是自己的记录。
Tags: 推送, badge, json
苹果相关 | 评论:0
| 阅读:20566