通常情况下,IOS系统用NSUserDefaults存储数据信息,但是对于一些私密信息,比如密码、证书等等,就需要使用更为安全的keychain了,keychain里保存的信息不会因App被删除而丢失。所以,可以利用这个keychain这个特点来保存设备唯一标识。
使用keyChain,我们需要导入Security.framework ,keychain的操作接口声明在头文件SecItem.h里。直接使用SecItem.h里方法操作keychain,需要写的代码较为复杂,我们可以使用已经封装好了的工具类KeychainItemWrapper来对keychain进行操作。
KeychainItemWrapper是apple官方例子“GenericKeychain”里一个访问keychain常用操作的封装类,在官网上(也可以在从本人资源地址链接: https://pan.baidu.com/s/1CH99lx1S0X8wLY57Kpxudw提取码: smy5 )下载了GenericKeychain项目后,只需要把“KeychainItemWrapper.h”和“KeychainItemWrapper.m”拷贝到我们项目,并导入Security.framework 。不过该文件是手动释放的 所以要使用这个文件需要先做一些处理:如果要使用KeychainItemWrapper.h类 在CompileSources中选中该类 添加-fno-objc-arc
KeychainItemWrapper *keychain=[[KeychainItemWrapper alloc] initWithIdentifier:@"myKey" accessGroup:nil]; //myKey 自定义
//保存数据 保存一次即使删除程序 手机依旧保存其钥匙串 依旧可以由keychain获得
[keychain setObject:@"little Pig" forKey:(id)kSecAttrAccount];//账户名
[keychain setObject:@"123456" forKey:(id)kSecValueData];//账户密码
//从keychain里取出帐号密码
NSString *password = [keychain objectForKey:(id)kSecValueData];
//清空设置
[keychain resetKeychainItem];
其中方法“- (void)setObject:(id)inObject forKey:(id)key;”里参数“forKey”的值应该是Security.framework 里头文件“SecItem.h”里定义好的key,用其他字符串做key程序会出错!
获取一台设备的唯一识别符
一.UDID(Unique Device Identifier),顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成。
二.UUID(Universally Unique Identifier) 中文意思是通用唯一识别码
在IOS7中UDID被禁止使用,UUID在APP重新运行或者重新安装后 两次获取的标识符不一样。由于IOS系统存储的数据都是在sandBox里面,一旦删除App,sandBox也不复存在。好在有一个例外,那就是keychain(钥匙串)。
现在常用的是UUID+keychain结合来实现这个需求
UUID是Universally Unique Identifer的缩写,中文意思是通用唯一识别码。它是让分布式系统中的所有元素,都能有唯一的辨识资讯,而不需要透过中央控制端来做辨识资讯的指定。这样,每个人都可以建立不与其它人冲突的UUID。在此情况下,就不需考虑数据库建立时的名称重复问题。苹果公司建议使用UUID为应用生成唯一标识
字符串。
- (NSString*)uuid {
CFUUIDRef uuid = CFUUIDCreate( nil );
CFStringRef uuidString = CFUUIDCreateString( nil, uuid );
NSString * result = (NSString *)CFBridgingRelease(CFStringCreateCopy( NULL, uuidString));
CFRelease(uuid);
CFRelease(uuidString);
return result;
}
现在我们获取到了一个UUID,虽然这个标识是唯一的,但是这样还是无法保证每一次的唯一性,因为当你每次调用这个方法或者把应用卸载了,UUID会重新生成一个不同的。这个时候keychain就起到了作用。所以整个逻辑是这样的:先从keychain取UUID, 如果能取到,就用这个比对,如果取不到就重新生成一一个保存起来。keychain独 立在App之外,是和系统统一等级的,所
以你不用担心它挂掉。
keychain是苹果公司Mac OS中的密码管理系统。它在Mac OS 8.6中被导入,并且包括在了所有后续的Mac OS版本中,包括Mac OS X。一个钥匙串可以包含多种类型的数据:密码(包括网站,FTP服务器,SSH帐户,网络共享,无线网络,群组软件,加密磁盘镜像等),私钥,电子证书和加密笔记等。iOS端同样有个keychain帮助我们管理这些敏感信息。
保存UUID代码:
- (void)saveUuidWithKeyChain {
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc] initWithIdentifier:@"UUID" accessGroup:nil];
NSString *strUUID = [keychainItem objectForKey: (id)kSecValueData];
if (strUUID == nil || [strUUID isEqualToString:@""])
{
[keychainItem setObject:[self uuid] forKey:
(id)kSecValueData];
}
}
注:这个方法中accessGroup :这个参数如果一些App设 置相同的话,是可以共享的。
从keyChain获取UUID的代码如下:
- (NSString *)getKeychain {
KeychainItemWrapper *keychainItem = [[KeychainItemWrapper alloc]initWithIdentifier:@"UUID" accessGroup:nil];
NSString *strUUID = [keychainItem objectForKey:(id)kSecValueData];
[keychainItem resetKeychainItem];
return strUUID;
}
至此,基本上唯-标识的几个方法算是写完了,大家可以测试一下,卸载应用再重新装,从keychain读取的UUID还是和之前- -样。
但这里有个不确定因素,就是手机系统恢复出厂设置或者抹掉所有数据的话,这个方法也可能不起作用了,因为它是依靠钥匙串在生存,钥匙串挂掉的话它也就失效了。