iOS设备唯一标识保存、钥匙串

 

 

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或其它地方。

 

NSUUID NSUUID在iOS 6中才出现,这跟CFUUID几乎完全一样,只不过它是Objective-C接口。+ (id)UUID 是一个类方法,调用该方法可以获得一个UUID。通过下面的代码可以获得一个UUID字符串:

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

 

跟CFUUID一样,这个值系统也不会存储,每次调用的时候都会获得一个新的唯一标示符。如果要存储的话,你需要自己存储。在我读取NSUUID时,注意到获取到的这个值跟CFUUID完全一样(不过也可能不一样)

 

广告标示符(IDFA-identifierForIdentifier) 这是iOS 6中另外一个新的方法,advertisingIdentifier是新框架AdSupport.framework的一部分。ASIdentifierManager单例提供了一个方法advertisingIdentifier,通过调用该方法会返回一个上面提到的NSUUID实例。

NSString *adId = [[[ASIdentifierManager sharedManager] advertisingIdentifier] UUIDString];

 

Vindor标示符 (IDFV-identifierForVendor)

 

 

 

    NSString *identifierForVendor = [NSString stringWithFormat:@"%@",[[[UIDevice currentDevice]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会被重置。

 

----------------------

<strong>兼容5,6,7的唯一标示;</strong>
- (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);
        return result;
    }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);
        return result;
    }
}
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);
        return result;
    }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);
        return result;
    }
}
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

示例代码
保存CFUUIDRef uuid = CFUUIDCreate(NULL);assert(uuid != NULL);CFStringRef uuidStr = CFUUIDCreateString(NULL, uuid);

[SSKeychain setPassword: [NSString stringWithFormat:@"%@", uuidStr]
forService:@"com.yourapp.yourcompany"account:@"user"];

从钥匙串读取UUID:

NSString *retrieveuuid = [SSKeychainpasswordForService:@"com.yourapp.yourcompany"account:@"user"];

 

 
 
 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值