iOS 获取设备惟一标示符的方法

 

在开发中会遇到应用须要记录设备标示,即便应用卸载后再安装也可从新识别的状况,在这写一种实现方式——读取设备的UUID(Universally Unique Identifier)并经过KeyChain记录。html

首先iOS中获取设备惟一标示符的方法一直随版本的更新而变化。iOS 2.0版本之后UIDevice提供一个获取设备惟一标识符的方法uniqueIdentifier,经过该方法咱们能够获取设备的序列号,这个也是目前为止惟一能够确认惟一的标示符。好景不长,由于该惟一标识符与手机一一对应,苹果以为可能会泄露用户隐私,因此在 iOS 5.0以后该方法就被废弃掉了;iOS 6.0系统新增了两个用于替换uniqueIdentifier的接口,分别是:identifierForVendor,advertisingIdentifier,但这两个接口会在应用从新安装时改变数值,并非惟一的标示符,因此开发者改成使用WiFi的mac地址来取代;iOS 7中苹果又封杀mac地址,因此开发者再次改变思路使用KeyChain来保存获取到的UDID,这样之后即便APP删了再装回来,也能够从KeyChain中读取回来。ios

首先保存设备的UUID,可使用类方法+ (id)UUID 是一个类方法,调用该方法能够得到一个UUID。经过下面的代码能够得到一个UUID字符串:git

NSString *uuid = [[NSUUID UUID] UUIDString];

也能够保存在iOS 6中新增的Vindor标示符 (IDFV-identifierForVendor),获取这个IDFV的新方法被添加在已有的UIDevice类中。跟advertisingIdentifier同样,该方法返回的是一个NSUUID对象。github

NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];

若是用户卸载了同一个vendor对应的全部程序,而后在从新安装同一个vendor提供的程序,此时identifierForVendor会被重置,因此这里要用到KeyChain来保存。
KeyChain(钥匙串)是使用苹果设备常常使用的,一般要调试的话,都得安装证书之类的,这些证书就是保存在KeyChain中,还有咱们平时浏览网页记录的帐号密码也都是记录在KeyChain中。iOS中的KeyChain相比OS X比较简单,整个系统只有一个KeyChain,每一个程序均可以往KeyChain中记录数据,并且只能读取到本身程序记录在KeyChain中的数据。iOS中Security.framework框架提供了四个主要的方法来操做KeyChain:安全

  • SecItemCopyMatching(CFDictionaryRef query, CFTypeRef *result);//查询OSStatus
  • SecItemAdd(CFDictionaryRef attributes, CFTypeRef *result); //添加OSStatus
  • SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate);//更新KeyChain中的ItemOSStatus
  • SecItemDelete(CFDictionaryRef query)//删除KeyChain中的ItemOSStatus

这四个方法参数比较复杂,一旦传错就会致使操做KeyChain失败,文档中介绍的比较详细,你们能够查查官方文档。而苹果提供的KeyChain使用起来略麻烦,因此这里推荐一个第三方库SAMKeyChains.SAMKeyChains对苹果安全框架API进行了简单封装,支持对存储在钥匙串中密码、帐户进行访问,包括读取、删除和设置。SAMKeyChains使用简单,经过实例代码即可掌握。app

//保存一个UUID字符串到钥匙串:
CFUUIDRef uuid = CFUUIDCreate(NULL);
assert(uuid != NULL);
CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);
 [SAMKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStr]
 forService:@"com.yourapp.yourcompany"account:@"user"];
 
//从钥匙串读取UUID:
NSString *retrieveuuid = [SAMKeychain passwordForService:@"com.yourapp.yourcompany"account:@"user"];
 
**注意: setPassword和passwordForSevice方法中的**services 和 accounts 参数应该是一致的。

更多详细用法说明能够看SAMKeyChains Documentation框架

基本的实现思路即是这样,下面是具体的一种具体实现代码,仅供参考。ide

+ (NSString *)getDeviceId
{
    NSString * currentDeviceUUIDStr = [SAMKeychain passwordForService:@" "account:@"uuid"];
    if (currentDeviceUUIDStr == nil || [currentDeviceUUIDStr isEqualToString:@""])
    {
        NSUUID * currentDeviceUUID  = [UIDevice currentDevice].identifierForVendor;
        currentDeviceUUIDStr = currentDeviceUUID.UUIDString;
        currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
        currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
        [SAMKeychain setPassword: currentDeviceUUIDStr forService:@" "account:@"uuid"];
    }
    return currentDeviceUUIDStr;
}
相关文章
相关标签/搜索