zoukankan      html  css  js  c++  java
  • iOS开发之——keychain使用

     iOS的keychain服务提供了一种安全的保存私密信息(密码,序列号,证书等)的方式。每个ios程序都有一个独立的keychain存储。从ios 3.0开始,跨程序分享keychain变得可行。

    使用苹果官方发布的KeychainItemWrapper或者SFHFKeychainUtils很方便。

    苹果已经有现成的类封装好了keychain,KeychainItemWrapper.h和KeychainItemWrapper.m文件,可以在GenericKeychain实例里找到。

     下面就使用keychain来实现存取用户名和密码。

     

    代码如下:

     

    DMKeyChain.h

    #import <Foundation/Foundation.h>
    #import <Security/Security.h>
    @interface DMKeyChain : NSObject
    /**
     *  保存数据
     *
     *  @param service key值
     *  @param data    存储值
     */
    + (void)save:(NSString *)service data:(id)data;
    /**
     *  读取数据
     *
     *  @param service key值
     *
     *  @return 存储的值
     */
    + (id)load:(NSString *)service ;
    /**
     *  删除某个数据
     *
     *  @param service 对应的key
     */
    + (void)delete:(NSString *)service;
    @end

     

     

    DMKeyChain.m

    #import "DMKeyChain.h"

    @implementation DMKeyChain
    + (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)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);
    }

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

    + (void)delete:(NSString *)service {
        NSMutableDictionary *keychainQuery = [self getKeychainQuery:service];
        SecItemDelete((__bridge_retained CFDictionaryRef)keychainQuery);
    }
    @end

     

  • 相关阅读:
    Android笔记之调用系统相机拍照
    Android笔记之RoundedImageView
    Java笔记之public、protected、default和private
    Android笔记之ExpandableListView(悬浮吸顶Demo)
    Android笔记之Fragment中创建ViewModel的正确方式
    Android代号、版本及API级别之间的对应关系
    【Phabricator】教科书一般的Phabricator安装教程(配合官方文档并带有踩坑解决方案)
    【Ansible】记一次技术博客害死人的经历——ansible模板变量注入探究
    【linux杂谈】遇到REMOTE HOST IDENTIFICATION HAS CHANGED怎么办?
    【linux杂谈】在SSH连接中,openssh如何解决'Connection refused'错误?
  • 原文地址:https://www.cnblogs.com/linxiu-0925/p/5311705.html
Copyright © 2011-2022 走看看