版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。
CFUUID从iOS2.0开始,CFUUID就已经出现了。它是CoreFoundatio包的一部分,因此API属于C语言风格。CFUUIDCreate方法用来创建CFUUIDRef,并且可以获得一个相应的NSString,如下代码:
CFUUIDRef cfuuid = CFUUIDCreate(kCFAllocatorDefault);NSString *cfuuidString = (NSString*)CFBridgingRelease(CFUUIDCreateString(kCFAllocatorDefault, cfuuid));
获得的这个CFUUID值系统并没有存储。每次调用CFUUIDCreate,系统都会返回一个新的唯一标示符。如果你希望存储这个标示符,那么需要自己将其存储到NSUserDefaults, Keychain, Pasteboard或其它地方。
NSUUIDNSUUID在iOS 6中才出现,这跟CFUUID几乎完全一样,只不过它是Objective-C接口。+ (id)UUID 是一个类方法,调用该方法可以获得一个UUID。通过下面的代码可以获得一个UUID字符串:
NSString *uuid = [[NSUUID UUID] UUIDString];
跟CFUUID一样,这个值系统也不会存储,每次调用的时候都会获得一个新的唯一标示符。如果要存储的话,你需要自己存储。在我读取NSUUID时,注意到获取到的这个值跟CFUUID完全一样(不过也可能不一样)
NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];
Vindor标示符 (IDFV-identifierForVendor)
NSString *identifierForVendor = [NSStringstringWithFormat:@"%@",[[[UIDevicecurrentDevice]identifierForVendor]UUIDString]];//判断是否是在某个手机上第一次下载唯一标识
这种叫法也是在iOS 6中新增的,不过获取这个IDFV的新方法被添加在已有的UIDevice类中。跟advertisingIdentifier一样,该方法返回的是一个NSUUID对象。
NSString *idfv = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
苹果官方的文档中对identifierForVendor有如下这样的一段描述 :
The value of this property is the same for apps that come from the same vendor running on the same device. A different value is returned for apps on the same device that come from different vendors, and for apps on different devices regardless of vendor.
如果满足这样的条件,那么获取到的这个属性值就不会变:相同的一个程序里面-相同的vindor-相同的设备。如果是这样的情况,那么这个值是不会相同的:相同的程序-相同的设备-不同的vindor,或者是相同的程序-不同的设备-无论是否相同的vindor。
看完上面的内容,我有这样的一个疑问“vendor是什么”。我首先想到的是苹果开发者账号。但事实证明这是错误的。接着我想可能是有一个AppIdentifierPrefix东西,跟钥匙串访问一样,可以在多个程序间共享。同样,这个想法也是的。最后证明,vendor非常简单:一个Vendor是CFBundleIdentifier(反转DNS格式)的前两部分。例如,com.doubleencore.app1 和com.doubleencore.app2 得到的identifierForVendor是相同的,因为它们的CFBundleIdentifier 前两部分是相同的。不过这样获得的identifierForVendor则完全不同:com.massivelyoverrated 或net.doubleencore。
在这里,还需要注意的一点就是:如果用户卸载了同一个vendor对应的所有程序,然后在重新安装同一个vendor提供的程序,此时identifierForVendor会被重置。
----------------------
兼容5,6,7的唯一标示;- (NSString *) uniqueDeviceIdentifier{if(IS_IOS_7){ NSString *identifierForVendor = [NSString stringWithFormat:@"%@",[[[UIDevice currentDevice]identifierForVendor]UUIDString]]; NSLog(@"identifierForVendor=%@",identifierForVendor); NSString *stringToHash = [NSString stringWithFormat:@"%@%@",identifierForVendor,DEVICE_TOKEN_PASS]; NSLog(@"stringToHash = %@",stringToHash); NSString *result = [NSString md5:stringToHash]; NSLog(@"result = %@",result);returnresult; }else{ NSString *macaddress = [[UIDevice currentDevice] macaddress]; NSLog(@"macaddress = %@",macaddress); NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,DEVICE_TOKEN_PASS]; NSLog(@"stringToHash = %@",stringToHash); NSString *result = [NSString md5:stringToHash]; NSLog(@"result = %@",result);returnresult; } }NSString *) uniqueDeviceIdentifier{if(IS_IOS_7){ NSString *identifierForVendor = [NSString stringWithFormat:@"%@",[[[UIDevice currentDevice]identifierForVendor]UUIDString]]; NSLog(@"identifierForVendor=%@",identifierForVendor); NSString *stringToHash = [NSString stringWithFormat:@"%@%@",identifierForVendor,DEVICE_TOKEN_PASS]; NSLog(@"stringToHash = %@",stringToHash); NSString *result = [NSString md5:stringToHash]; NSLog(@"result = %@",result);returnresult; }else{ NSString *macaddress = [[UIDevice currentDevice] macaddress]; NSLog(@"macaddress = %@",macaddress); NSString *stringToHash = [NSString stringWithFormat:@"%@%@",macaddress,DEVICE_TOKEN_PASS]; NSLog(@"stringToHash = %@",stringToHash); NSString *result = [NSString md5:stringToHash]; NSLog(@"result = %@",result);returnresult; } }
https://www.jianshu.com/p/1d2ea0d51ed9
https://www.jianshu.com/p/e6afb12c1e9e
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的值和之前不同。
苹果官方钥匙串:https://github.com/fenglongteng/KeychainItemWrapper
1.钥匙串KeyChian 是保存在沙盒之外的存储数据,相当于Dictionary, 所有应用都可以获取和保存,因此当一个软件卸载之后完全不影响里面的数据,这样当软件重新安装之后,还可以获取里面的原数据。
钥匙串的第三方框架SFHFKeychainUtils:
引入Security.frameWork框架。
引入头文件:SFHKeychainUtils.h.
//保存数据
[SFHFKeychainUtils storeUsername:@"dd" andPassword:@"aa" forServiceName:SERVICE_NAME updateExisting:1 error:nil]; [SFHFKeychainUtils deleteItemForUsername:@"dd" andServiceName:SERVICE_NAME error:nil];
BOOL s = [SFHFKeychainUtils storeUsername:name andPassword:pswd forServiceName:server updateExisting:NO error:nil];
//获取密码
NSString * psw = [SFHFKeychainUtils getPasswordForUsername:name andServiceName:server error:nil];
2.KeychainItemWrapper
将“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework
下面是我在appDelegate.m中的代码:因为我不需要在应用间共享keychain中的内容,所以accessGroup设置为nil
//钥匙串存储 -(void)keychainstoreWith:(NSString *)filepathstr cameraname:(NSString *)cameraname filekey:(NSString *)preorbackfilekey cameranamekey:(NSString *)preorbackcameranamekey identifier:(NSString *)keychainidentifier{ KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:keychainidentifier accessGroup:nil]; // [wrapper setObject:@"" forKey:(id)kSecAttrAccount];//这里的key是系统预置的 // [wrapper setObject:@"" forKey:(id)kSecValueData]; [wrapper setObject:filepathstr forKey:preorbackfilekey]; [wrapper setObject:cameraname forKey:preorbackcameranamekey]; } //从钥匙串中取 -(void)getdatafromkeychainWithfilekey:(NSString *)preorbackfilekey cameranamekey:(NSString *)preorbackcameranamekey identifier:(NSString *)keychainidentifier{ KeychainItemWrapper *wrapper = [[KeychainItemWrapper alloc] initWithIdentifier:@"hzym" accessGroup:nil]; // NSString *username = [wrapper objectForKey:(id)kSecAttrAccount]; // NSString *password = [wrapper objectForKey:(id)kSecValueData]; NSString *username = [wrapper objectForKey:preorbackfilekey]; NSString *password = [wrapper objectForKey:preorbackcameranamekey]; }
3.第三方:SSKeychain