iOS程序猿之keyChain保存登录名和密码

keyChain保存用户名和密码

iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式,每个ios程序都有一个独立的keychain存储。相对于NSUserDefaults、文件保存等一般方式,keychain保存更为安全,而且keychain里保存的信息不会因App被删除而丢失,所以在重装App后,keychain里的数据还能使用。

下面贴上自己封装的keyChain保存用户登录名和密码的代码:
WQKeyChain.h

#import <Foundation/Foundation.h>

@interface WQKeyChain : NSObject

/**
 *  保存数据
 *
 *  @param service 标识符; eg: @"com.公司名.app.allInfo"
 *  @param data    保存的数据; eg:保存账号密码时,该参数可以是一个包含用户名和密码的字典
 */
+ (void)saveWithServie:(NSString *)service data:(id)data;

/**
 *  根据标示符读取保存的数据
 *
 *  @param service 标识符;
 *
 *  @return 返回保存的数据;
 */
+ (id)loadDataWithService:(NSString *)service;

/**
 *  根据标识符删除保存的数据
 *
 *  @param service 标识符;
 */
+ (void)deleteDataWithService:(NSString *)service;

@end

WQKeyChain.m
#import "WQKeyChain.h"

@implementation WQKeyChain

// 保存数据
+ (void)saveWithServie:(NSString *)service data:(id)data
{
    // 1.先根据标识符获取keyChainQuery
    NSMutableDictionary *keyChainQuery = [self getKeychainQuery:service];
    // 2.删除旧数据
    SecItemDelete((__bridge_retained CFDictionaryRef)keyChainQuery);
    // 3.添加新数据
    [keyChainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:((__bridge_transfer id)kSecValueData)];
    // 添加keyChainQuery到keychain
    SecItemAdd((__bridge_retained CFDictionaryRef)keyChainQuery, NULL);
}

// 根据标示符读取保存的数据
+ (id)loadDataWithService:(NSString *)service
{
    id returnData = nil;
    // 1.先根据标识符获取keyChainQuery
    NSMutableDictionary *keyChainQuery = [self getKeychainQuery:service];
    // 2. 配置keyChainQuery的设置
    [keyChainQuery setObject:(id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
    [keyChainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne forKey:(__bridge_transfer id)kSecMatchLimit];
    CFDataRef keyData = nil;
    if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keyChainQuery, (CFTypeRef *)&keyData) == noErr) {
        @try {
            returnData = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData *)keyData];
        }
        @catch (NSException *exception) {
            NSLog(@"Unarchive of %@ failed: %@", service, exception);
        }
        @finally {
        }
    }
    return returnData;
}

// 根据标识符删除保存的数据
+ (void)deleteDataWithService:(NSString *)service
{
    // 1.先根据标识符获取keyChainQuery
    NSMutableDictionary *keyChainQuery = [self getKeychainQuery:service];
    // 2.删除
    SecItemDelete((__bridge_retained CFDictionaryRef)keyChainQuery);
}

#pragma mark - private 私有方法
// 从keyChain根据标识符获取keyChainQuery
+ (NSMutableDictionary *)getKeychainQuery:(NSString *)service {
    NSMutableDictionary *dictionary = [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];
    return dictionary;
}

@end

用户管理类

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

@interface UserDataManager : NSObject

/**
 *  保存用户信息
 *
 *  @param userName 用户名
 *  @param password 密码
 */
+ (void)saveUserInfoWithUserName:(NSString *)userName password:(NSString *)password;

/**
 *  读取用户名
 *
 *  @return 用户名字符串
 */
+ (NSString *)loadUserName;

/**
 *  读取密码
 *
 *  @return 密码字符串
 */
+ (NSString *)loadPassword;

/**
 *  删除用户信息
 */
+ (void)deleteUserInfo;

@end
UserDataManager.m
#import "UserDataManager.h"
#import "WQKeyChain.h"

@implementation UserDataManager

static NSString *const KEY_IN_KEYCHAIN = @"com.companyName.app.allinfo";
static NSString *const KEY_USERNAME = @"com.companyName.app.userName";
static NSString *const KEY_PASSWORD = @"com.companyName.app.password";

// 保存用户信息
+ (void)saveUserInfoWithUserName:(NSString *)userName password:(NSString *)password
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    [dic setObject:userName forKey:KEY_USERNAME];
    [dic setObject:password forKey:KEY_PASSWORD];
    [WQKeyChain saveWithServie:KEY_IN_KEYCHAIN data:dic];
}

// 读取用户名
+ (NSString *)loadUserName
{
    NSMutableDictionary *dic = [WQKeyChain loadDataWithService:KEY_IN_KEYCHAIN];
    return [dic objectForKey:KEY_USERNAME];
}

// 读取密码
+ (NSString *)loadPassword
{
    NSMutableDictionary *dic = [WQKeyChain loadDataWithService:KEY_IN_KEYCHAIN];
    return [dic objectForKey:KEY_PASSWORD];
}

// 删除用户信息
+ (void)deleteUserInfo
{
    [WQKeyChain deleteDataWithService:KEY_IN_KEYCHAIN];
}
@end

这里是对登录名和密码进行简单的本地存储,网上还有一些写的比较全的博客,这里附上链接:
点击打开链接

点击打开链接






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值