相信在我们存储一些数据的时候都会遇到一些苦恼,如果应用一旦被用户删除,那么设备中的信息就会被清除掉。此时,keychain就发挥了作用,当应用被用户删除掉时,保存在keychain中的数据还会存在,除非用户重装系统。那么我们就简单说明下keychain的使用吧!
一、以保存密码为例:
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
return [NSMutableDictionary dictionaryWithObjectsAndKeys:
(__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,
service, (__bridge_transfer id)kSecAttrService,
service, (__bridge_transfer id)kSecAttrAccount,
(__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock,(__bridge_transfer id)kSecAttrAccessible,
nil];
}
1.保存数据:
+ (void)save:(NSString *)service data:(id)data {
//Get search dictionary
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
//Delete old item before add new item
SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
//Add new object to search dictionary(Attention:the data format)
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(__bridge_transfer id)kSecValueData];
//Add item to keychain with the search dictionary
SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
NSLog(@"save url to keychain");
}
2.取数据:
+ (id)load:(NSString *)service {
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
//Configure the search setting
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
[keychainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
@try {
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
} @catch (NSException *e) {
NSLog(@"Unarchive of %@ failed: %@", service, e);
} @finally {
}
}
return ret;
}
3.删除数据:
+ (void)delete:(NSString *)service {
NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
}
二、在控制器中使用(我把上面的方法封装在了YNKeyChain这个类里面方便使用):
static NSString * const KEY_PASSWORD = @"ynwang.app.password";
//保存
- (IBAction)saveAction:(id)sender {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setObject:self.passwordTextField.text forKey:KEY_PASSWORD];
[YNKeyChain save:KEY_PASSWORD data:dictionary];
}
//删除
- (IBAction)deleteAction:(id)sender {
[YNKeyChain delete:KEY_PASSWORD];
}
//取数据
- (IBAction)showPasswordAction:(id)sender {
NSDictionary *dic = [YNKeyChain load:KEY_PASSWORD];
if (dic) {
self.passwordLabel.text = dic[KEY_PASSWORD];
}
else{
self.passwordLabel.text = @"空";
}
}
三、运行结果:
四、keychain的另一个重要的作用,就是可以共享同一个开发者账号的不同APP之间的信息,这样就实现了两个不同应用之间信息的共享。主要有两个步骤。
1.在APP target的bulib Setting里面添加Code Signing Entitlements为包含AceessGroup的分组信息的plist文件,否则会出现找不到文件的错误。如下图:
2.新建一个名字为Code Signing Entitlements中的plist文件,注意该文件的结构中最顶层的节点必须是一个名为“keychain-access-groups”的Array,并且该Array中每一项都是一个描述分组的NSString。对于String的格式也有相应要求,格式为:"AppIdentifier.com.*",其中AppIdentifier就是你的开发者帐号对应的ID。
原文链接:http://www.jianshu.com/p/ec8cab4bc0a4著作权归作者所有,转载请联系作者获得授权,并标注“简书作者”。
以上为keychain的简单使用,感谢会飞的咸鱼提供的文章参考。后续会继续更新,希望对大家有用。