先简单介绍下push的机制数据库
客户端经过安全
(void)registerForRemoteNotificationTypes:(UIRemoteNotificationType)types服务器
这个函数向APNs(Apple Push Service)注册push,types可标明接收的push的类型,声音,数字等。app
(void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken;iphone
当app成功注册通知后,会调用这个函数,并把deviceToken返回给应用。ide
而后咱们的程序就会把返回的这个deviceToken以及设备的udid及软件版本(淘宝 for iPhone仍是淘宝 for iPad)及系统版本,用户名等发送到咱们的服务器(下图中的provider)上,而后存储在数据库里。整个获取device token的过程可参见下图所示:函数
在须要发送push时,咱们的服务端就会取出要发送的设备的device token,而后如下图所示的结构,组成符合特定结构的字符串,而后将其发送到的APNs测试
APNs能够根据与APNs创建链接的Provider所使用的证书判断是要哪一个app请求发送的notification,继而把这个notification发送到的设备上。加密
下图为一个简单的从Provider到Device发送push的过程:spa
device token究竟是什么呢? 不一样的app的device token相同么? 一个设备会产生多个device token么? 一个的device token可能对应多个UDID么?
结论:device token是对APNs来讲,设备的标识符,与app无关,因此同一台设备上,不一样的app得到的device token是同样的; 一个设备可能会产生多个device token, 一个device token也可能对应多个UDID,下面进行解释。
device token是什么?
文档中以下描述的:
对于APS来讲,token是设备的标识符。device token不一样于UIDevice的uniqueIdentifier(即UDID),由于出于安全和隐私缘由,当设备被擦除后,token必须变化。
因此也就是说,通常状况下,token是不变的,可是在设备被擦除后,token会变的。
今天无意说在咱们的服务器上的数据库里,存在同一个UDID对应有多个token的状况,以前是没有考虑到设备擦除的状况,因此就怀疑是否是同一个 设备上同时装了taobao4iphone和taobao4ipad,而token是与app关联的,因此产生的这种状况,因而就找了ipad来作 测试,结果发现taobao4iphone和taobao4ipad收到的token是相同的,因此token应该是与app无关的,而是针对设备的(文 档上也是如此描述的),是设备的标识,那除了设备被擦除的状况外,设备的device token 应该是相同的,但是给他查出来的他的iPad的token和我log出来的device token是不一样的,后来就想到了,push是有两套的,development和product,即调试和release,在这两种状况下,服务端使用 的push证书是不同的,而程序使用的证书也不同,那同一个设备在development和distribution状况下收到的device token是否同样呢,因而就作了实验,实际结果以下
实验设备:
能够看出,同一个设备在development和distribution状况下,收到的device token是不一样的,而token是与app无关的。
综合文档及上述实验结果能够获得如下结果:
同一个udid对应有不一样的device token的状况暂时有以下两种:
设备擦除过,token变化过,老的新的都存储在数据库里
设备同时装过development和distribution的程序
不知道还有没有其它缘由形成的同一个设备有不一样的device token的状况,你们若是有什么相关的经验,能够补充一下。
无意说数据库里也有同一个device token对应多个UDID的状况,这种状况就比较诡异了,按理说不该该的,比较APNs把token做为设备的标识的,若是同一个device token能够对应多个udid,那发push不是就会混乱了么,在网上查了相关资料,发现还真的有这种状况,
设备令牌是怎么生成的呢?是每次创建TLS链接时,APNS经过前一层次(TLS层)里咱们提到的每台正常的iPhone惟一的设备证书(unique device certificate),并用令牌密钥(token key)加密生成的。
最重要的部分——每台iPhone独有的设备证书和密钥的来历
正常的iPhone刷系统以后,是没有设备证书和密钥的。这就是为何iPhone会须要链接到iTunes上进行激活——激活过程当中,Apple会分配给每台iPhone独一无二的设备证书(device certificate)和密钥(key) 。
iPhone OS 3.X 使用blacksn0w进行解锁 的过程,是不通过iTunes的,而blacksn0w自己又不生成对应的设备证书(device certificate)和密钥(key) ,所以这样解锁完的iPhone根本不可能与APNS创建任何的TLS连接,Push天然废了。
但当多个iPhone的设备证书(device certificate)彻底一致时,就存在必定概率使得多个iPhone得到相同的设备令牌(device token)
要修补这个问题,惟一的办法就是从新生成惟一且有效的设备证书(device certificate)和密钥(key) 。因而,最先,dev team推出了一个测试版补丁,Push fix by dev team(经过他们的twitter发布的,所以官网没有消息)。这个补丁初期颇有效。可是仅在iPhone 2G上比较正常。以后某人士发布pushfix 1.0了。因为使用了不一样的生成方法,所以在新版本iPhone上也正常工做了。因而风靡一时。
然而,以上两个补丁都有严重的隐患——他们使用了一个固定的证书做为设备证书(device certificate)。所以在不一样iPhone上的区别仅仅在于生成的密钥(key)不一样。 (待确认)
而随着这两个补丁的使用人数不断增长,使得出现得到相同设备令牌(device token)的iPhone数量大大增长了。
当这些相同设备令牌(device token)的iPhone上启用了同一个应用程序的Push的时候,就极有可能出现彼此间的Push串发的现象。——如某论坛目前N多人抱怨QQ的Push到别人iPhone上的状况就是如此。
以上大概解释了同一个device token对应多个UDID的缘由,
因为咱们后续也会把与用户相关的信息push到用户的设备上,因此这个问题,咱们也要考虑下应该怎么处理,不然也可能会出现,收到别人的物流的push。。。
另外,因为iOS5.0后,UIDevice中的uniqueIdentifier会逐步被废弃,因此,后面的版本中,咱们会使用把设备的mac地 址md5计算后的结果作为设备的惟一标识,用其去代替UDID上传到咱们的服务端上,可是不管是UDID仍是mac地址的md5值,都只是做为设备的标 识,在发送push时,惟一须要与设备相关的信息就是device token,因此这个应该不影响咱们的push。