iOS如何将APP的信息保存到沙盒之外(钥匙串中)

来源:互联网 发布:单片机编译链接 编辑:程序博客网 时间:2024/05/01 23:54

有时候我们需要将APP的某些信息保存到沙盒之外,比如判断是否是第一次安装该APP,如果将信息保存在当前APP的沙盒路径下,当删除该应用的时候,这条信息也会跟着一起被删除,显然这样是不行的。所以,要考虑其他的实现方法。我们可以把一些简单的信息比如某些标识或者用户的账号密码等保存到KeyChain中,这样就可以解决上面的问题了。

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

/** *  该类需要工作在mrc模式下,如果项目是arc,按照下面进行操作 *  选中工程->TARGETS->相应的target然后选中右侧的“Build Phases”,向下就找到“Compile Sources”了。然后在相应的文件后面添加:-fno-objc-arc参数 */

首先导入系统的框架:

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

.h文件:

复制代码
#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
复制代码

.m实现:

复制代码
#import "KeyChina.h"@implementation KeyChina+(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
复制代码

0 0
原创粉丝点击