昨晚看到 tw 上的 @undead__king 吐槽:apple的开发也太水了吧.一个设备对同一APP居然能同时存在两个有效的推送token,这下我没法彻底解决重复推送问题了

详细问了下原因,回答是:有可能是从iOS6降回5越狱造成的.现在有什么方案是可以唯一标识设备的吗?之前用openuid,后来发现卸载后再安装就变了

我们自己的应用也有推送,使用的也是 Apple 的推送。所以关注了一下。第二天早上找到我们 iOS 开发,询问了一下,我们的客户端使用的也是 openUDID 库(也就是第二条推里面的 openuid )。

openUDID 库的机制实际上是在自定义粘贴板用了一个特殊的名称来存储标识符,通过这种方法,其他使用该库的程序知道去什么地方获取已经生成的标识符。每台iOS设备的OpenUDID是通过第一个带有 openUDID SDK 包的 App 生成,如果你完全删除全部带有 openUDID SDK 包的App(比如恢复系统等),那么OpenUDID会重新生成,而且和之前的值会不同,相当于新设备。也就是这个 UDID 也不是绝对唯一的。

根据参考资料(见文末),苹果在新系统提供的 Advertiser Identifier 和 Identifier for Vendor(IDFV)也不唯一的。如果大家有兴趣,可以去看看。在 iOS 7 系统之后,没法对苹果手机进行追踪。如果苹果对同设备生成了2个有效的推送 token,那么没办法了。目前还不知道 Apple 生成 token 及 token 失效的规则?

顺便分析了一下我们本地的推送数据(有效的):

总数据:679322

1,同 token 对应多个 UDID:

先按照 token 进行去重统计,结果是677260;

然后统计所有 token 重复次数超过1次的,结果是20162,正好是总数据减去去重统计结果的差值,说明重复的数据都只有2个。

进一步分析重复的这部分数据:

如果 bigVersion(版本标识)是2012的,重复的有33条,重复的是 iPhone 一条,iPad 一条,因为当时当时我们的产品有2个版本。

如果 bigVersion(版本标识)是2013的,重复的有14条,重复的是客户端多次调用导致的(deviceType 和 token 都是一样的,DB 生成时间到秒级别都是相同的),我们DB要对 deviceType 和 token 做唯一性约束,防止脏数据产生。已经存在的数据会处理掉。

剩下重复的数据就是2012一条,2013一条,按照bigVersion 来单独统计都不会重复,但是统计就会重复了。

2,同 UDID 对应多个 token:

按照 UDID 进行去重统计,结果是 653094;

统计所有 UDID 重复次数超过1次的,结果是18362,说明还有很多数据重复的次数超过2次了。按照重复次数排序如下:

UDID重复次数 | 重复的数据个数 ————- | ————

2 18124
3 177
4 24
5 7
6 6
7 3
8 1
9 1
10 1
11 5
12 3
15 2
17 1
30 1
77 1
91 1
97 144
2458 1
4561 1

进一步分析重复次数最高的2条数据:eeb56ba8945401082d5012d74dec8452udidfor5(重复2458次)、0f607264fc6318a92b9e13c65db7cd3cudidfor5(重复4561次)。

结合用户信息表,按照2个 UDID 分别进行查询:

UDID:eeb56ba8945401082d5012d74dec8452udidfor5,版本标识是2013。用户信息表数目为:2492。

按照客户端版本统计:

客户端版本 数目 —- ———– —— 3.0 5
3.3 2    
3.4 6    
3.4.1 55    
3.5 37    
3.5.1 3    
3.5.2 23    
3.5.3 240    
3.6 71    
3.6.1 164    
3.7 1886    

按照系统版本统计:

客户端版本 数目 —- ———– —— 7.0 1206
7.0.2 874    
7.0.3 412    

UDID:0f607264fc6318a92b9e13c65db7cd3cudidfor5,版本标识是2012,app_user表数目为:4720。

按照客户端版本统计:

客户端版本 数目 —- ———– —— 1.6.2 2
2.0 4    
2.1 18    
2.2 29    
2.3 26    
2.4 2824    
2.6 1917    

按照系统版本统计:

系统版本 数目 —- ———– ——
7.0 1206
7.0.2 2254
7.0.3 1255

从数据来看,大部分 UDID 重复的数据是系统是7.0之后的,应用的都是4.0之前的。因为当时还没更新到最新的 UDID 库,只是不知道为什么用户还在安装那个版本?或许那些越狱的商店里面还停留在这个版本?

如果再有重复的,只能尝试跟踪用户的 UDID 记录,分析活跃设备,然后删除不活跃设备 token。

参考资料:

1,知乎关于 OpenUDID 的讨论

2,The Developer’s Guide to Unique Identifiers

3,iOS唯一标示符引导