iOS钥匙串(KeyChain)和设备id(uuid)

前言

在开发过程中,我们经常会被要求获取每个设备的唯一标示,以便后台做相应的处理。

一:UUID采用 IDFV

  • 全名:identifierForVendor
    获取代码:
    NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
    来源:iOS6.0及以后

  • 说明:顾名思义,是给Vendor标识用户用的,每个设备在所属同一个Vender的应用里,都有相同的值。其中的Vender是指应用提供商,但准确点说,是通过BundleID的反转的前两部分进行匹配,如果相同就是同一个Vender,例如对于com.taobao.app1, com.taobao.app2 这两个BundleID来说,就属于同一个Vender,共享同一个idfv的值。和idfa不同的是,idfv的值是一定能取到的,所以非常适合于作为内部用户行为分析的主id,来标识用户,替代OpenUDID。

  • 注意:如果用户将属于此Vender的所有App卸载,则idfv的值会被重置,即再重装此Vender的App,idfv的值和之前不同。

二:钥匙串:Keychain

  • 介绍


    iOS钥匙串(KeyChain)和设备id(uuid)_第1张图片
  • 钥匙串用途
    我们可以获取到UUID,然后把UUID保存到KeyChain里面。
    这样以后即使APP删了再装回来,也可以从KeyChain中读取回来。使用keyChain Sharing还可以保证同一个开发商(teamID同)的所有程序针对同一台设备能够获取到相同的不变的UDID。但是刷机或重装系统后uuid还是会改变。

  • 苹果官方提供的库
    KeychainItemWrappe 然而很多人说并不好用。

  • 钥匙串bug
    钥匙串我使用的是第三方库SSKeychain,经过长期删除重装软件发现钥匙串访问获取数据并不稳定,存在问题:有时候会获取不到钥匙串中的数据,且这段时间都无法获取。但是过段时间就可以获取了。

三:xcode设置

项目2若要使用项目1的Keychain则项目2要开启Keychain Sharing 且 Keychain Groups要包含项目1。 项目1的Keychain Sharing 没有要求。

iOS钥匙串(KeyChain)和设备id(uuid)_第2张图片
项目 1
iOS钥匙串(KeyChain)和设备id(uuid)_第3张图片
项目 2

四:代码

使用第三方SSKeychain。

#import 
//获取uuid且保存到钥匙串 卸载过后又安装的话读取钥匙串uuid
+ (NSString*)getUUID{
    NSString * currentDeviceUUIDStr = nil;
    //由于钥匙串有一定概率拿不到uuid,错误原因又很难说,而且拿不到的时候一小段时间都拿不到,所以尽量少用钥匙串拿数据,这里就用了NSUserDefaults减少使用钥匙串。钥匙串只在卸载app后第一次拿uuid使用。
    currentDeviceUUIDStr = [[NSUserDefaults standardUserDefaults]objectForKey:@"uuid"];
    if (TestStringIsBlank(currentDeviceUUIDStr)) {
        currentDeviceUUIDStr = [SSKeychain passwordForService:@"com.baidu.HuaHuaLive" account:@"uuid"];
        if(!TestStringIsBlank(currentDeviceUUIDStr)){
            [[NSUserDefaults standardUserDefaults]setObject:currentDeviceUUIDStr forKey:@"uuid"];
        }
    }
//    NSError *error = nil;
//    while (error) {
//        error = nil;
//        currentDeviceUUIDStr = [SSKeychain passwordForService:@"com.baidu.HuaHuaLive"account:@"uuid" error:&error];
//    }
    if (TestStringIsBlank(currentDeviceUUIDStr))
    {
        /**
         *此uuid在相同的一个程序里面-相同的vindor-相同的设备下是不会改变的
         *此uuid是唯一的,但应用删除再重新安装后会变化,采取的措施是:只获取一次保存在钥匙串中,之后就从钥匙串中获取
         **/
        currentDeviceUUIDStr  = [UIDevice currentDevice].identifierForVendor.UUIDString;
        currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
        currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
        //若获取不到就手动生成
        if (TestStringIsBlank(currentDeviceUUIDStr)) {
            CFUUIDRef uuidRef = CFUUIDCreate(kCFAllocatorDefault);
            CFStringRef cfuuid = CFUUIDCreateString(kCFAllocatorDefault, uuidRef);
            CFRelease(uuidRef);
            currentDeviceUUIDStr = [((__bridge NSString *) cfuuid) copy];
            currentDeviceUUIDStr = [currentDeviceUUIDStr stringByReplacingOccurrencesOfString:@"-" withString:@""];
            currentDeviceUUIDStr = [currentDeviceUUIDStr lowercaseString];
            CFRelease(cfuuid);
        }
    //password:密码 serviece:应用标识(最好使用bundleID) account:账户名
        [SSKeychain setPassword: currentDeviceUUIDStr forService:@"com.baidu.HuaHuaLive" account:@"uuid"];
        [[NSUserDefaults standardUserDefaults]setObject:currentDeviceUUIDStr forKey:@"uuid"];
    }
    return currentDeviceUUIDStr;
}

你可能感兴趣的:(iOS钥匙串(KeyChain)和设备id(uuid))