使用KeyChain保存用户信息

1.新建一个LYKeychainTool类,导入系统Security框架 ,LYKeychainTool.h文件实现如下:

//
//  LYKeychainTool.h
//  keyChainTest
//
//  Created by Liyu on 2017/6/2.
//  Copyright © 2017年 liyu. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <Security/Security.h>

@interface LYKeychainTool : NSObject

/**
 *  储存字符串到钥匙串
 *  @param sValue 对应的Value
 *  @param sKey   对应的Key
 */
+ (void)saveKeychainValue:(NSString *)sValue key:(NSString *)sKey;

/**
 *  从钥匙串获取字符串
 *  @param sKey 对应的Key
 *  @return 返回储存的Value
 */
+ (NSString *)readKeychainValue:(NSString *)sKey;

/**
 *  从钥匙串删除字符串
 *  @param sKey 对应的Key
 */
+ (void)deleteKeychainValue:(NSString *)sKey;

@end

2.LYKeychainTool.m文件实现如下:

//
//  LYKeychainTool.m
//  keyChainTest
//
//  Created by Liyu on 2017/6/2.
//  Copyright © 2017年 liyu. All rights reserved.
//

#import "LYKeychainTool.h"

@implementation LYKeychainTool

+ (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];
}

+ (void)saveKeychainValue:(NSString *)sValue key:(NSString *)sKey {
    NSMutableDictionary * keychainQuery = [self getKeychainQuery:sKey];
    SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
    [keychainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:sValue] forKey:(__bridge_transfer id)kSecValueData];
    SecItemAdd((__bridge_retained CFDictionaryRef)keychainQuery, NULL);
}

+ (NSString *)readKeychainValue:(NSString *)sKey {
    NSString *ret = nil;
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey];
    [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 CFDictionaryRef)keychainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            ret = (NSString *)[NSKeyedUnarchiver unarchiveObjectWithData:(__bridge NSData *)keyData];
        } @catch (NSException *e) {
            NSLog(@"Unarchive of %@ failed: %@", sKey, e);
        } @finally {
        }
    }
    if (keyData)
        CFRelease(keyData);
    return ret;
}

+ (void)deleteKeychainValue:(NSString *)sKey {
    NSMutableDictionary *keychainQuery = [self getKeychainQuery:sKey];
    SecItemDelete((__bridge CFDictionaryRef)keychainQuery);
}

@end

3.ViewController 调用

//
//  ViewController.m
//  keyChainTest
//
//  Created by Liyu on 2017/6/2.
//  Copyright © 2017年 liyu. All rights reserved.
//

#import "ViewController.h"
#import "LYKeychainTool.h"

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UITextField *userNameTextField;

@property (weak, nonatomic) IBOutlet UITextField *passwordTextField;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];

}

- (IBAction)saveBtn:(id)sender {
    [LYKeychainTool saveKeychainValue:self.userNameTextField.text key:@"userName"];
    [LYKeychainTool saveKeychainValue:self.passwordTextField.text key:@"password"];
}

- (IBAction)readeBtn:(id)sender {
    self.userNameTextField.text = [NSString stringWithFormat:@"读取到用户名:%@",[LYKeychainTool readKeychainValue:@"userName"]];
    self.passwordTextField.text = [NSString stringWithFormat:@"读取到用户密码:%@",[LYKeychainTool readKeychainValue:@"password"]];
}

- (IBAction)deleteBtn:(id)sender {
    [LYKeychainTool deleteKeychainValue:@"userName"];
    [LYKeychainTool deleteKeychainValue:@"password"];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];

}


@end

4.效果如下图:


最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 178,445评论 25 709
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,563评论 30 472
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 136,465评论 19 139
  • 01复仇——从哪里跌倒就从哪里爬起来 NBA是一个擅长写故事的地方,不是说他有剧本,而是篮球就如人生,比赛就如故事...
    Amazing_初阅读 839评论 5 3
  • 我们终于分手了,虽然我有些不习惯,有些失落,但你真的没有来找我,我知道我们真的不可能了,那就祝福你吧,再见了,我最亲爱的
    桃之夭夭不见不爱阅读 125评论 0 0

友情链接更多精彩内容