• iOS--KeyChina 简单使用


    今天了解一下KeyChina,之前保存的用户信息都放在NSUserDefaults,这样很不安全,现在写的话我会放在KeyChina中,因为他存储的信息还是比较安全的,Keychain的信息是存在于每个应用(app)的沙盒之外的,所以keychain里保存的信息不会因App被删除而丢失,在用户重新安装App后依然有效,数据还在。(就是将一些敏感信息,储存起来);

    接下来我们来简单的集成一下吧,保存用户的账号和密码,还有其他用处,这里并没有介绍:

    集成之前先说一下,KeyChina现在不支持ARC,所以需要我们手动的配置工程,在代码中会有体现,

    首先导入系统的框架:

    然后我们新建一个类:KeyChina;

    .m:

    #import <Foundation/Foundation.h>
    #import <Security/Security.h>
    
    @interface KeyChina : NSObject
    /**
     *  用KeyChaina去保存用户名和密码
     */
    +(void)save:(NSString *)service data:(id)data;
    /**
     *  从KeyChina取出用户名和密码
     */
    +(id)load:(NSString *)service;
    /**
     *  从KeyChina中删除用户名和密码
     */
    + (void)delete:(NSString *)service;
    
    
    @end

    .h实现:

    #import "KeyChina.h"
    @implementation KeyChina
    
    /**
     *  该类需要工作在mrc模式下,如果项目是arc,按照下面进行操作
     *  选中工程->TARGETS->相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了。然后在相应的文件后面添加:-fno-objc-arc参数
     */
    
    +(NSMutableDictionary *)getKeychinaQuery:(NSString *)service{
        
        return [NSMutableDictionary dictionaryWithObjectsAndKeys:(id)kSecClassGenericPassword, (id)kSecClass, service, (id)kSecAttrService, service, (id)kSecAttrAccount, (id)kSecAttrAccessibleAfterFirstUnlock, (id)kSecAttrAccessible, nil];
        
    }
    
    #pragma mark -- 写入
    +(void)save:(NSString *)service data:(id)data{
        
        //Get search dictionary
        NSMutableDictionary *keyChinaQuery = [self getKeychinaQuery:service];
        //Delete old item before add new item
        SecItemDelete((CFDictionaryRef)keyChinaQuery);
        //Add new object to search dictionary(Attention:the data format)
        [keyChinaQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data] forKey:(id)kSecValueData];
        //Add item to keychain with the search dictionary
        SecItemAdd((CFDictionaryRef)keyChinaQuery, NULL);
    }
    #pragma mark -- 读取
    + (id)load:(NSString *)service{
        
        id ret = nil;
        NSMutableDictionary *keychinaQuery = [self getKeychinaQuery:service];
        //Configure the search setting
        //Since in our simple case we are expecting only a single attribute to be returned (the password) we can set the attribute kSecReturnData to kCFBooleanTrue
        [keychinaQuery setObject:(id)kCFBooleanTrue forKey:(id)kSecReturnData];
        [keychinaQuery setObject:(id)kSecMatchLimitOne forKey:(id)kSecMatchLimit];
        
        CFDataRef keyData = NULL;
        if (SecItemCopyMatching((CFDictionaryRef)keychinaQuery, (CFTypeRef *)&keyData) == noErr) {
            @try {
                ret = [NSKeyedUnarchiver unarchiveObjectWithData:(NSData *)keyData];
            } @catch (NSException *e) {
                NSLog(@"Unarchive of %@ failed: %@", service, e);
            } @finally {
            }
        }
        if (keyData)
            CFRelease(keyData);
            return ret;
        
    }
    #pragma mark -- 删除
    +(void)delete:(NSString *)service{
        NSMutableDictionary *keychinaQuery = [self getKeychinaQuery:service];
        SecItemDelete((CFDictionaryRef)keychinaQuery);
    }
    
    
    @end

    在需要的地方调用:

    #import "ViewController.h"
    #import "KeyChina.h"
    @interface ViewController ()
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        // Do any additional setup after loading the view, typically from a nib.
        NSString * const KEY_USERNAME_PASSWORD = @"com.company.app.usernamepassword";
        NSString * const KEY_USERNAME = @"com.company.app.username";
        NSString * const KEY_PASSWORD = @"com.company.app.password";
        
        NSMutableDictionary *userNamePasswordKVPairs = [NSMutableDictionary dictionary];
        [userNamePasswordKVPairs setObject:@"userName" forKey:KEY_USERNAME];
        [userNamePasswordKVPairs setObject:@"password" forKey:KEY_PASSWORD];
    
        // A、将用户名和密码写入keychain
       [KeyChina save:KEY_USERNAME_PASSWORD data:userNamePasswordKVPairs];
        // B、从keychain中读取用户名和密码
        NSMutableDictionary *readUsernamePassword = (NSMutableDictionary *)[KeyChina load:KEY_USERNAME_PASSWORD];
        NSString *userName = [readUsernamePassword objectForKey:KEY_USERNAME];
        NSString *password = [readUsernamePassword objectForKey:KEY_PASSWORD];
        NSLog(@"username = %@", userName);
        NSLog(@"password = %@", password);
        
        // C、将用户名和密码从keychain中删除
        [KeyChina delete:KEY_USERNAME_PASSWORD];
    }
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        // Dispose of any resources that can be recreated.
        
    }
    
    @end

    OK了!!!

  • 相关阅读:
    error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏 E:OCX
    JQUERY解析XML IE8的兼容问题
    IE11下,IIS7.5不自动生成__doPostBack事件
    IE11无法支持Forms认证,,,也就是无法保存COOKIE
    IIS7.5真变态,服务器时间格式导致不生成WebResource.axd
    django ajax MTV与MVC 多对多创建方式
    django F与Q查询 事务 only与defer
    模型层
    模板层(模板语法)
    django 路由层 伪静态网页 虚拟环境 视图层
  • 原文地址:https://www.cnblogs.com/LzwBlog/p/5744135.html
Copyright © 2020-2023  润新知