// 封装
#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

@interface SecItemHelper : NSObject
+ (void)saveFromName:(NSString *)name data:(id)data;
+ (id)loadFromName:(NSString *)name;
+ (void)deletedataFromName:(NSString *)name;
@end

NS_ASSUME_NONNULL_END

#import “SecItemHelper.h”

@implementation SecItemHelper
+ (void)saveFromName:(NSString *)name data:(id)data
{
NSMutableDictionary *keychainQuery = [self getKeychainQuery:name];
// 清空
SecItemDelete((CFDictionaryRef)keychainQuery);
// 赋值
[keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
// 添加
SecItemAdd((CFDictionaryRef)keychainQuery, NULL);
}

+ (id)loadFromName:(NSString *)name
{
id ret = nil;
NSMutableDictionary *keychainQuery = [self getKeychainQuery:name];
[keychainQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
[keychainQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
CFDataRef keyData = NULL;
if (SecItemCopyMatching((CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr)
{
@try
{
ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
}
@catch (NSException *e)
{
NSLog(@”Unarchive of %@ failed: %@”, name, e);
}
@finally
{

}
}
if (keyData)
{
CFRelease(keyData);
}
return ret;
}

+ (void)deletedataFromName:(NSString *)name
{
NSMutableDictionary *keychainQuery = [self getKeychainQuery:name];
SecItemDelete((CFDictionaryRef)keychainQuery);
}

+ (NSMutableDictionary *)getKeychainQuery:(NSString *)name
{
NSMutableDictionary *dic = [NSMutableDictionary dictionary];
[dic setValue:(id)kSecClassGenericPassword forKey:(id)kSecClass];
[dic setValue:name forKey:(id)kSecAttrAccount];
[dic setValue:name forKey:(id)kSecAttrService];
// 解锁后可以的安全蛇者
[dic setValue:(id)kSecAttrAccessibleAfterFirstUnlock forKey:(id)kSecAttrAccessible];
return dic;
}

@end
// 调用
#import “ViewController.h”
#import “SecItemHelper.h”

@interface ViewController ()

@end

@implementation ViewController

– (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.

NSString *name = NSStringFromClass(ViewController.class);

NSMutableDictionary *dic =[NSMutableDictionary dictionary];
[dic setValue:@”xiaoming” forKey:@”user”];
[dic setValue:@”123456″ forKey:@”password”];

[SecItemHelper saveFromName:name data:dic];

id data = [SecItemHelper loadFromName:name];

NSLog(@”%@”,data);

// [SecItemHelper deletedata:name];
// id data2 = [SecItemHelper load:name];
// NSLog(@”%@”,data2);
}

– (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

@end
// 译文

kSecAttrAccessibleWhenUnlocked
当解锁时,kSec具有可访问性 推荐使用 iCloud同步
kSecAttrAccessibleAfterFirstUnlock
*次解锁后可访问kSec iCloud同步
kSecAttrAccessibleAlways
一直访问 不建议使用 iCloud同步
kSecAttrAccessibleWhenPasscodeSetThisDeviceOnly
当密码仅设置此设备时,kSec Attr可访问 iCloud不同步
kSecAttrAccessibleWhenUnlockedThisDeviceOnly
只有在解锁此设备时才能访问kSec Attr iCloud不同步
kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly
只有在首次解锁此设备后才能访问kSec Attr iCloud不同步
kSecAttrAccessibleAlwaysThisDeviceOnly
kSec Attr始终只能访问此设备 iCloud不同步

kSecClassInternetPassword
表示Internet密码项的值。

kSecClassCertificate
表示证书项的值。

kSecClassKey
表示加密密钥项的值。

kSecClassIdentity
表示标识项的值。