前言
在开发过程中,我们经常会被要求获取每个设备的唯一标示,以便后台做相应的处理。
一: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
-
介绍
钥匙串用途
我们可以获取到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 没有要求。
四:代码
使用第三方SSKeychain。
#import <SSKeychain.h>
//获取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;
}