【转】APNs消息推送完整讲解
在项目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代码:
- [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound | UIRemoteNotificationTypeBadge)];
通过registerForRemoteNotificationTypes方法,告诉应用程序,能接受push来的通知。
在项目的AppDelegate中添加下面的方法来获取deviceToken:
- - (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken {
- NSString *token = [NSString stringWithFormat:@"%@", deviceToken];
- NSLog(@"My token is:%@", token);
- }
- - (void)application:(UIApplication *)app didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {
- NSString *error_str = [NSString stringWithFormat: @"%@", error];
- NSLog(@"Failed to get token, error:%@", error_str);
- }
获取到的deviceToken,我们可以提交给后台应用程序,发送通知的后台应用程序除了需要知道deviceToken之外,还需要一个与APNS连接的证书。
(自iOS开发文档"Local and Push Notification Programming Guide"里与iOS相关的部分翻译)
-----------------------------------------▲客户端处理------------------------------------------
建议每次程序启动的时候都调用registerForRemoteNotificationTypes来重新获取设备相关的token,而不要缓存token.
这是因为,如果用户重装了iOS或者用户换了设备并且恢复程序备份到一个新的设备,都将导致这个token值不一样。
当iOS收到远程消息时,
如果应用程序isn't running in the foreground,iOS会处理这个消息,比如弹出一个框、在应用程序的icon上显示红色数字。
然后如果用户通过点击弹框进入程序,iOS会启动程序并调用application:didFinishLaunchingWithOptions并且拿远程消息的payload进行传参.
如果用户直接点击app icon进入程序,iOS会启动程序并同样调用application:didFinishLaunchingWithOptions,但是传参将不会有远程消息的任何信息。
如果应用程序is running in the foreground,就会调用application:didReceiveRemoteNotification.
----------------------------------------------▲APNs----------------------------------------------
IOS设备会持久连接APNs以接受远程消息。
provider发送消息到APNs,然后APNs再发送到目标IOS设备。(这个传输是单向的。)
这个消息的内容含两部分:设备token和payload.
反馈服务--
有时候APNs发送消息到某设备(token)某程序(bundle identifier)但是该设备并没有这个程序,多次这种情况之后,APNs会通知provider,通过其连接的一个反馈服务(a feedback service)。
反馈服务为每一个程序维护了一个失效设备列表,provider应该获取这个列表从而停止向APNs发送以这些设备为目的地的某程序的远程消息。
APNs的安全架构--
provider需要一个有效证书才能和APNs连接(这个证书有目标程序的Bundle identifier信息)。
与APNs连接后,provider向APNs发送的消息带有设备token(由目标程序连接provider然后发来token),APNs以此找到目标设备,然后看目标设备里的目标程序有接受推送的证书,APNs以此验证给目标设备的目标程序发送的消息是合法的。
注意:远程消息是不可靠的。
----------------------------------------▲Provider-------------------------------------------
Payload--
最多256bytes。
本地化alert:
eg:"alert" : {"loc-key":"GAME_PLAY_REQUEST_FORMAT","loc-args":["Jenna","Frank"]},
程序包里面的本地化字符串如下:
"GAME_PLAY_REQUEST_FORMAT" = "%@ and %@ have invited you to play Monopoly";
这样,最后显示alert的字符串就是:
"Jenna and Frank have invited you to play Monopoly"
一个JSON Payload的完整例子(为了性能,建议去掉空白字符)
{
"aps" :
{
"alert" : "Message received from Bob",
"badge" : 5,
"sound" : "bingbong.aiff"
},
"myCustomData" : ["bang", "bang、bang、bang"],
"myCustomData2": 42
}
----------------------------------------▲部署-------------------------------------------
要部署provider端client/server程序,需要来自苹果的SSL证书。下称provider证书。
provider证书对应于特定的iOS Application(Bundle identifier)。
同时,provider证书分为开发测试和产品两种版本,对应于两种APNs环境:
Sandbox(Development) :可用模拟器测试。地址是gateway.sandbox.push.apple.com: TCP 2195
Production(Distribution):gateway.push.apple.com: TCP 2195
同
时,provision profile也对应了两个版本:Development和Distribution.(The Distribution
provision profile is a requirement for submitting your application to
the App Store.)
可以在xcode里看iOS
application所处何环境:看编译选项里的code-signing identity,如果是"iPhone
Developer:Firstname Lastname"证书与provisioning
profile匹配成对,说明是sandbox环境。如果是"iPhone
Distribution:Companyname"证书与provision
profile匹配成对,说明是production环境。根据release和debug分别配置code-signing
identity选项的证书将会是一个好主意。
注意:尽管SSL证书(即provider证书)没有放到iOS
application的providion profile里,但是ios
application是否支持远程消息推送依然取决于profile,因为profile内含开发者证书、设备ID、application
ID(Bundle identifier)、"是否支持推送"(在苹果开发者网站上配置证书的时候配置的)等信息。(The provisioning
profile is a collection of assets that associates developers of an
application and their devices with an authorized development team and
enables those devices to be used for testing.The profile contains
certificates,device identifiers,the application's bundle ID,and all
entitlement,including <aps-environment>.)
以文本方式打
开*.mobileprovision,会看到里面类似xml格式,其中<key>Entitlements</key>里包含
了<key>aps-environment</key>,说明支持远程消息推送,<key>aps-
environment</key>下面的<string>说明是调试版本还是发布版本(对应于Sandbox环境和
Production环境)。
●安装证书到服务端
你应该安装SSL证书和私匙到你的provider程序运行的服务器上。
步骤如下:
0.安装该证书到mac电脑的钥匙串。
1.打开钥匙串,在左侧面板上点击我的证书栏。
2.找到这个SSL证书,展开会看到证书和私匙。
3.我们选中证书和私匙,然后导出为"个人信息交换文件"--即扩展名为p12的文件。
4.provider服务器程序最好用Ruby和Perl这类语言,可以方便的处理"个人信息交换文件"里的证书。mac下打开终端输入以下命令以把证书转换为这类语言乐于交流的格式:
openssl pkcs12 -in CertificateName.p12 -out CertificateName.pem -nodes
5.把这pem文件拷到服务器上并安装到某个适当的位置。
----------------------------------------▲Provider与APNs连接----------------------------------------
●连接APNs之前provider需要具备什么
APNs提供的连接接口是二进制的、streaming TCP socket、异步 的。
Production环境是通过gateway.push.apple.com:2195,Development环境是gateway.sandbox.push.apple.com:2195。
Provider可以建立多个与APNs的连接。每个都得用TLS(or SSL)来建立安全通道,需要用到SSL证书(就是上面提到的provider连接APNs要用到的SSL证书)。
----------------------
Note
要建立与APNs的TLS会话,需要在provider服务器上安装Entrust Secure CA根证书。Moa OS
X是默认已安装的,其他系统的话,可以没有安装,可以从Entrust SSL
Certificates的网站http://www.entrust.net/下载安装根证书。
----------------------
●发送消息的二进制接口和消息的数据包格式
消息须是网络字节顺序(即大尾顺序),消息里面的payload部分不可以超过256字节,且不得以'\0'结尾。
消息格式见"The Binary Interface and Notification Formats"章节。
●The Feedback Service
feedback service包含了这样的列表:某iOS应用程序对应的"设备"("设备"用二进制格式的设备token来标识)。--这些设备是由于各种原因而不能接收APNs发来的消息。
Provider应该定期查询这个列表,并且作出对应处理,如:停止向这些的设备发送消息。
provider访问feedback server通过一个与发送消息类似的二进制接口。
Production环境通过feedback.push.apple.com:2196来建立连接,Development通过feedback.sandbox.push.apple.com:2196。
feedback service和发送消息是不同的服务接口(但都属于APNs),他的连接方式和发送消息是一样的。也要通过证书建立SSL连接,连接后你不需要发送任何命令,直接开始读取流一直读完为止,然后provider要解析读到的数据。
数据是由多个这样的格式组成的:
| 四字节时间 | 2字节的token 长度 | 32字节的设备token |
关
于"四字节时间":Provider需要判断对应设备的这个iOS应用程序有没有在该时间之后重新像provider发送注册推送消息所获得的设备
token。如果没有,就认为该设备失效了,需停止向该设备发送消息。如果有,那就是这个设备失效过,但是现在又有效了,只是feedback
service还没来得及刷新列表。
【转】APNs消息推送完整讲解的更多相关文章
- APNs消息推送完整讲解
在项目的AppDelegate中的didFinishLaunchingWithOptions方法中加入下面的代码: [[UIApplication sharedApplication] registe ...
- oc学习之路----APNS消息推送从证书到代码(2015年4月26号亲试可用)
前言:看这篇博客之前要准备:首先的有一个99刀的个人开发者账号或者199刀的企业开发者账号,其次你用的是apns消息推送,(本人之前四处打听有没有其他消息推送的方法:收获如下:首先如果想做到apns的 ...
- 基于C++ 苹果apns消息推送实现(2)
1.该模块的用途C++ 和 Openssl 代码 它实现了一个简单的apns顾客 2.配套文件:基于boost 的苹果apns消息推送实现(1) 3.最初使用的sslv23/sslv2/sslv3仅仅 ...
- IOS 基于APNS消息推送原理与实现(JAVA后台)
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple Pu ...
- 转:IOS 基于APNS消息推送原理与实现(JAVA后台)
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple ...
- IOS 基于APNS消息推送原理与实现(JAVA后台)--转
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple ...
- iOS 基于APNS消息推送原理与实现(包括JAVA后台代码)
Push的原理: Push 的工作机制可以简单的概括为下图 图中,Provider是指某个iPhone软件的Push服务器,这篇文章我将使用.net作为Provider. APNS 是Apple ...
- APNS消息推送实现
转自:http://blog.csdn.net/biaobiaoqi/article/details/8058503 一.消息推送原理: 在实现消息推送之前先提及几个于推送相关概念,如下图1-1: 1 ...
- 基于APNs最新HTTP/2接口实现iOS的高性能消息推送(服务端篇)
1.前言 本文要分享的消息推送指的是当iOS端APP被关闭或者处于后台时,还能收到消息/信息/指令的能力. 这种在APP处于后台或关闭情况下的消息推送能力,通常在以下场景下非常有用: 1)IM即时通讯 ...
随机推荐
- Python绑定方法,未绑定方法,类方法,实例方法,静态方法
>>> class foo(): clssvar=[1,2] def __init__(self): self.instance=[1,2,3] def hehe(self): pr ...
- Bellman-Ford最短路径
对于前面说到的最短路径的求解方法,不能解决负权边的情况,而Bellman-Ford却可以 共有n个顶点,m条边,每次输入u[i],v[i],w[i],代表从u[i]到v[i]的距离是w[i],对于所有 ...
- 北京市小升初 zz
发信人: django (牛魔王), 信区: SchoolEstate 标 题: 北京市小升初掐尖方式的演变过程(看后恍然大悟) 发信站: 水木社区 (Thu Feb 4 10:51:23 201 ...
- 织梦(dedecms)系统常用全局变量调用标签及路径
{dede:global.cfg_memberurl/} 指的是会员中心 对应/member/目录 {dede:global.cfg_cmsurl/} 对应的是网站根目录/ {dede:global. ...
- 关于php多线程的记录
最近需要对3W台服务器进行下发脚本,如果一个一个执行,时间大约在2个小时,特别的慢,于是修改程序,采用php的多线程去分发,大概在10分钟左右完成,下面记录下这次的经验和理解: 我所理解的php的多线 ...
- 借助取色工具ColorPix对Pycharm编辑器设定自己喜欢的代码颜色_20161202
1.Pycharm编辑器怎么设定自己喜欢的颜色,前几天看爬虫博客,看博主贴出的代码颜色很是喜欢,如下图,设置了好多次找不到他设定的颜色. 2.下班回家想起来之前做表的时候用到过一个取色工具ColorP ...
- 京东B2B的4种供销模式
B2B的4种供销模式,以京东商城为例: FBP 京东给商家一个独立操作的后台, 商家五地入库(北京,上海,广州,成都,武汉),从仓储 到配送 到客服都是京东来操作, 京东本身自营的产品所有能享 ...
- UVa 414 - Machined Surfaces
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=94&page=s ...
- WinExec
WinAPI: WinExec - 运行外部程序 //声明 WinExec( lpCmdLine: LPCSTR; {文件名和参数; 如没指定路径会按以下顺序查找: 程序目录/当前目录/Syste ...
- makefile多目录的.c 格式.cpp混合编译
# # c.cpp混合编译的makefile模板 # # BIN = test.exe CC = gcc CPP = g++ #这里只加入库头文件路径及库路径 INCS = -I"c:/mi ...