iOS 的各种识别码
在iOS系统中,获取设备唯一标识的方法有很多:
1. x UDID (Unique Device Identifier,已过期)
2. x OPEN UDID (已过期)
3. 广告标示符(IDFA-identifierForIdentifier)
4. Vendor标示符 (IDFV-identifierForVendor)
5. 推送 device token+bundle_id
6. UUID(Universally Unique Identifier)
7. x MAC Address (iOS 7 后所有获取的 MAC 地址都相同)
1. x UDID
UDID的全称是Unique Device Identifier,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成(越狱的设备通过某些工具可以改变设备的UDID)。移动网络 可利用UDID来识别移动设备,但是,从IOS5.0(2011年8月份)开始,苹果宣布将不再支持用uniqueIdentifier方法获取设备的 UDID,iOS5以下是可以用的。在2013年3月21日苹果已经通知开发者:从2013年5月1日起,访问UIDIDs的程序将不再被审核通过,替代 的方案是开发者应该使用“在iOS 6中介绍的Vendor或Advertising标示符”。所以UDID是绝对不能用啦。
2. x OPEN UDID (已过期)
OPEN UDID,没有用到MAC地址,同时能保证同一台设备上的不同应用使用同一个OpenUDID,只要用户设备上有一个使用了OpenUDID的应用存在 时,其他后续安装的应用如果获取OpenUDID,都将会获得第一个应用生成的那个。但是根据贡献者的代码和方法,和一些开发者的经验,如果把使用了 OpenUDID方案的应用全部都删除,再重新获取OpenUDID,此时的OpenUDID就跟以前的不一样。可见,这种方法还是不保险。此项目已过期。
3. 广告标示符(IDFA-identifierForIdentifier)
广告标示符,是iOS 6中另外一个新的方法,提供了一个方法advertisingIdentifier,通过调用该方法会返回一个NSUUID实例,最后可以获得一个 UUID,由系统存储着的。不过即使这是由系统存储的,但是有几种情况下,会重新生成广告标示符。如果用户完全重置系统((设置程序 -> 通用 -> 还原 -> 还原位置与隐私) ,这个广告标示符会重新生成。另外如果用户明确的还原广告(设置程序-> 通用 -> 关于本机 -> 广告 -> 还原广告标示符) ,那么广告标示符也会重新生成。关于广告标示符的还原,有一点需要注意:如果程序在后台运行,此时用户“还原广告标示符”,然后再回到程序中,此时获取广 告标示符并不会立即获得还原后的标示符。必须要终止程序,然后再重新启动程序,才能获得还原后的广告标示符。
4. Vendor标示符 (IDFV-identifierForVendor)
Vendor标示符,也是在iOS 6中新增的,跟advertisingIdentifier一样,该方法返回的是一个 NSUUID对象,可以获得一个UUID。如果满足条件“相同的一个程序里面-相同的vendor-相同的设备”,那么获取到的这个属性值就不会变。如果 是“相同的程序-相同的设备-不同的vendor,或者是相同的程序-不同的设备-无论是否相同的vendor”这样的情况,那么这个值是不会相同的。
推送token+bundle_id的方法:
- 应用中增加推送用来获取token
- 获取应用bundle_id
- 根据token+bundle_id进行散列运算
5. 推送 device token+bundle_id
apple push token保证设备唯一,但必须有网络情况下才能工作,该方法不依赖于设备本身,但依赖于apple push,而苹果push有时候会抽风的。
这个 token 的解释不太详细,从网上找到的各种分析来看,结论是这个号码基本稳定,就是重装应用不会改变。但系统升级后不确定。比如从 iOS4 升到 iOS5 据说会变。另外据说这个 token 的有效期只是两年。另外苹果官方是这样阐述的:"An application should register [with APN servers] every time it launches and give its provider the current token". 既然苹果这样建议,也证明了这个 token 不适合作为设备识别来用。
6. UUID(Universally Unique Identifier)
UUID是Universally Unique Identifier的缩写,中文意思是通用唯一识别码。它是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指 定。这样,每个人都可以建立不与其它人冲突的 UUID。在此情况下,就不需考虑数据库建立时的名称重复问题。苹果公司建议使用UUID为应用生成唯一标识字符串。
iOS中获取UUID的代码如下:
-(NSString*) uuid { CFUUIDRef puuid = CFUUIDCreate( nil ); CFStringRef uuidString = CFUUIDCreateString( nil, puuid ); NSString * result = (NSString *)CFStringCreateCopy( NULL, uuidString); CFRelease(puuid); CFRelease(uuidString); return [result autorelease]; }
开发者可以在应用第一次启动时调用一 次,然后将该串存储起来,以便以后替代UDID来使用。但是,如果用户删除该应用再次安装时,又会生成新的字符串,所以不能保证唯一识别该设备。这就需要 各路高手想出各种解决方案。所以,之前很多应用就采用MAC Address。但是现在如果用户升级到iOS7(及其以后的苹果系统)后,他们机子的MAC Address就是一样的,没办法做区分,只能弃用此方法,重新使用UUID来标识。如果使用UUID,就要考虑应用被删除后再重新安装时的处理。
一个解决的办法是:UUID一般只生成一次,保存在iOS keychain 里面,如果应用删除了,重装应用之后它的UUID还是一样的,除非系统重置 。
有几个项目是做这个的:
https://github.com/fabiocaccamo/FCUUID
http://blackpixel.com/blog/2012/03/unique-identifier-is-dead-long-live-unique-identifier.html (https://github.com/blackpixel/BPXLUUIDHandler)
https://github.com/ObjColumnist/MCSMKeychainItem
参考博客:
http://www.cnblogs.com/BigPolarBear/p/3359526.html
http://iosameer.blogspot.fr/2012/08/alternative-to-ios-device-uuid.html
http://www.cnblogs.com/samniu/p/3673781.html
http://www.cocoachina.com/bbs/read.php?tid=144524
http://www.cnblogs.com/smileEvday/p/udid.html