iOS 获取设备唯一标示符的方法详解
在开发中会遇到应用需要记录设备标示,即使应用卸载后再安装也可重新识别的情况,在这写一种实现方式——读取设备的UUID(UniversallyUniqueIdentifier)并通过KeyChain记录。
首先iOS中获取设备唯一标示符的方法一直随版本的更新而变化。iOS2.0版本以后UIDevice提供一个获取设备唯一标识符的方法uniqueIdentifier,通过该方法我们可以获取设备的序列号,这个也是目前为止唯一可以确认唯一的标示符。好景不长,因为该唯一标识符与手机一一对应,苹果觉得可能会泄露用户隐私,所以在iOS5.0之后该方法就被废弃掉了;iOS6.0系统新增了两个用于替换uniqueIdentifier的接口,分别是:identifierForVendor,advertisingIdentifier,但这两个接口会在应用重新安装时改变数值,并不是唯一的标示符,所以开发者改为使用WiFi的mac地址来取代;iOS7中苹果又封杀mac地址,所以开发者再次改变思路使用KeyChain来保存获取到的UDID,这样以后即使APP删了再装回来,也可以从KeyChain中读取回来。
首先保存设备的UUID,可以使用类方法+(id)UUID是一个类方法,调用该方法可以获得一个UUID。通过下面的代码可以获得一个UUID字符串:
NSString*uuid=[[NSUUIDUUID]UUIDString];
也可以保存在iOS6中新增的Vindor标示符(IDFV-identifierForVendor),获取这个IDFV的新方法被添加在已有的UIDevice类中。跟advertisingIdentifier一样,该方法返回的是一个NSUUID对象。
NSString*idfv=[[[UIDevicecurrentDevice]identifierForVendor]UUIDString];
如果用户卸载了同一个vendor对应的所有程序,然后在重新安装同一个vendor提供的程序,此时identifierForVendor会被重置,所以这里要用到KeyChain来保存。
KeyChain(钥匙串)是使用苹果设备经常使用的,通常要调试的话,都得安装证书之类的,这些证书就是保存在KeyChain中,还有我们平时浏览网页记录的账号密码也都是记录在KeyChain中。iOS中的KeyChain相比OSX比较简单,整个系统只有一个KeyChain,每个程序都可以往KeyChain中记录数据,而且只能读取到自己程序记录在KeyChain中的数据。iOS中Security.framework框架提供了四个主要的方法来操作KeyChain:
- SecItemCopyMatching(CFDictionaryRefquery,CFTypeRef*result);//查询OSStatus
- SecItemAdd(CFDictionaryRefattributes,CFTypeRef*result);//添加OSStatus
- SecItemUpdate(CFDictionaryRefquery,CFDictionaryRefattributesToUpdate);//更新KeyChain中的ItemOSStatus
- SecItemDelete(CFDictionaryRefquery)//删除KeyChain中的ItemOSStatus
这四个方法参数比较复杂,一旦传错就会导致操作KeyChain失败,文档中介绍的比较详细,大家可以查查官方文档。而苹果提供的KeyChain使用起来略麻烦,所以这里推荐一个第三方库SAMKeyChains.SAMKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码、账户进行访问,包括读取、删除和设置。SAMKeyChains使用简单,通过实例代码便可掌握。
//保存一个UUID字符串到钥匙串: CFUUIDRefuuid=CFUUIDCreate(NULL); assert(uuid!=NULL); CFStringRefuuidStr=CFUUIDCreateString(NULL,uuid); [SAMKeychainsetPassword:[NSStringstringWithFormat:@"%@",uuidStr] forService:@"com.yourapp.yourcompany"account:@"user"]; //从钥匙串读取UUID: NSString*retrieveuuid=[SAMKeychainpasswordForService:@"com.yourapp.yourcompany"account:@"user"];
**注意:setPassword和passwordForSevice方法中的**services和accounts参数应该是一致的。
更多详细用法说明可以看SAMKeyChainsDocumentation
基本的实现思路便是这样,下面是具体的一种具体实现代码,仅供参考。
+(NSString*)getDeviceId { NSString*currentDeviceUUIDStr=[SAMKeychainpasswordForService:@""account:@"uuid"]; if(currentDeviceUUIDStr==nil||[currentDeviceUUIDStrisEqualToString:@""]) { NSUUID*currentDeviceUUID=[UIDevicecurrentDevice].identifierForVendor; currentDeviceUUIDStr=currentDeviceUUID.UUIDString; currentDeviceUUIDStr=[currentDeviceUUIDStrstringByReplacingOccurrencesOfString:@"-"withString:@""]; currentDeviceUUIDStr=[currentDeviceUUIDStrlowercaseString]; [SAMKeychainsetPassword:currentDeviceUUIDStrforService:@""account:@"uuid"]; } returncurrentDeviceUUIDStr; }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。、