简单实现KeyChain实例

目录结构如下:

AppDelegate.m

 1 //
 2 //  AppDelegate.m
 3 //  KeyChain
 4 //
 5 //  Created by apple on 14-12-26.
 6 //  Copyright (c) 2014年 ll. All rights reserved.
 7 //
 8
 9 #import "AppDelegate.h"
10
11 @interface AppDelegate ()
12
13 @end
14
15 @implementation AppDelegate
16
17
18 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19     // Override point for customization after application launch.
20     ViewController *vc = [[ViewController alloc] init];
21     self.window.rootViewController = vc;
22     [self.window makeKeyAndVisible];
23     return YES;
24 }
25
26 - (void)applicationWillResignActive:(UIApplication *)application {
27     // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
28     // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
29 }
30
31 - (void)applicationDidEnterBackground:(UIApplication *)application {
32     // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
33     // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
34 }
35
36 - (void)applicationWillEnterForeground:(UIApplication *)application {
37     // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
38 }
39
40 - (void)applicationDidBecomeActive:(UIApplication *)application {
41     // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
42 }
43
44 - (void)applicationWillTerminate:(UIApplication *)application {
45     // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
46 }
47
48 @end

KeyChain.h

 1 //
 2 //  KeyChain.h
 3 //  KeyChain
 4 //
 5 //  Created by apple on 14-12-26.
 6 //  Copyright (c) 2014年 ll. All rights reserved.
 7 //
 8
 9 #import <Foundation/Foundation.h>
10 #import <Security/Security.h>
11
12 @interface KeyChain : NSObject
13
14 + (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier;
15
16 + (void)save:(NSString *)service data:(id)data;
17
18 + (id)load:(NSString *)service;
19
20 + (void)delete:(NSString *)service;
21
22 @end

KeyChain.m

 1 //
 2 //  KeyChain.m
 3 //  KeyChain
 4 //
 5 //  Created by apple on 14-12-26.
 6 //  Copyright (c) 2014年 ll. All rights reserved.
 7 //
 8 /**
 9  *__bridge_transfer , __bridge_retained c和oc类型之间转换,,可统一使用__bridge替换
10  */
11 #import "KeyChain.h"
12 static NSString *serviceName = @"com.mycompany.myAppServiceName";
13
14 @implementation KeyChain
15
16 + (NSMutableDictionary *)newSearchDictionary:(NSString *)identifier
17 {
18
19     NSMutableDictionary * searchDictionary = [[NSMutableDictionary alloc] init];
20     NSData *encodeInditifier = [identifier dataUsingEncoding:NSUTF8StringEncoding];
21     [searchDictionary setObject:(__bridge_transfer id)kSecClassGenericPassword
22                          forKey:(__bridge_transfer id)kSecClass];
23     [searchDictionary setObject:encodeInditifier forKey:(__bridge_transfer id)kSecAttrGeneric];
24     [searchDictionary setObject:encodeInditifier forKey:(__bridge_transfer id)kSecAttrAccount];
25     [searchDictionary setObject:(__bridge_transfer id)kSecAttrAccessibleAfterFirstUnlock
26                          forKey:(__bridge_transfer id)kSecAttrAccessible];
27
28     //[searchDictionary setObject:serviceName forKey:(__bridge id)kSecAttrService];
29
30     return searchDictionary;
31 }
32
33 +(void)save:(NSString *)service data:(id)data
34 {
35     NSMutableDictionary *keyChainQuery = [self newSearchDictionary:service];
36     /**
37      *  delete old
38      */
39     SecItemDelete((__bridge_retained CFDictionaryRef)keyChainQuery);
40     [keyChainQuery setObject:[NSKeyedArchiver archivedDataWithRootObject:data]
41                       forKey:(__bridge_transfer id)kSecValueData];
42     /**
43      *  add new
44      */
45     SecItemAdd((__bridge_retained CFDictionaryRef)keyChainQuery, nil);
46
47 }
48
49 +(id)load:(NSString *)service
50 {
51     id ret = nil;
52     NSMutableDictionary *keyChainQuery = [self newSearchDictionary:service];
53     [keyChainQuery setObject:(id)kCFBooleanTrue
54                       forKey:(__bridge_transfer id)kSecReturnData];
55     [keyChainQuery setObject:(__bridge_transfer id)kSecMatchLimitOne
56                       forKey:(__bridge_transfer id)kSecMatchLimit];
57     CFDataRef keyData = NULL;
58
59     if (SecItemCopyMatching((__bridge_retained CFDictionaryRef)keyChainQuery, (CFTypeRef*)&keyData) == noErr)
60     {
61         ret = [NSKeyedUnarchiver unarchiveObjectWithData:(__bridge_transfer NSData*)keyData];
62     }
63
64 //    if (keyData) {
65 //
66 //        CFRelease(keyData);
67 //    }
68 //
69
70     return ret;
71 }
72
73 +(void)delete:(NSString *)service
74 {
75     NSMutableDictionary *keyChainQuery = [self newSearchDictionary:service];
76
77     SecItemDelete((__bridge_retained CFDictionaryRef)keyChainQuery);
78
79 }
80
81
82 @end

ViewController.h

 1 //
 2 //  ViewController.h
 3 //  KeyChain
 4 //
 5 //  Created by apple on 14-12-26.
 6 //  Copyright (c) 2014年 ll. All rights reserved.
 7 //
 8
 9 #import <UIKit/UIKit.h>
10 #import "KeyChain.h"
11
12 @interface ViewController : UIViewController
13
14 + (void)savePassWord:(NSString *)password;
15
16 + (id)readPassWord;
17
18 + (void)deletePassWord;
19
20
21 @end

ViewController.m

  1 //
  2 //  ViewController.m
  3 //  KeyChain
  4 //
  5 //  Created by apple on 14-12-26.
  6 //  Copyright (c) 2014年 ll. All rights reserved.
  7 //
  8
  9 #import "ViewController.h"
 10 static NSString * const KEY_IN_KEYCHAIN = @"com.wuqian.app.allinfo";// 字典在keychain中的key
 11 static NSString * const KEY_PASSWORD = @"com.wuqian.app.password"; //  密码在字典中的key
 12
 13 @interface ViewController ()
 14 {
 15     UITextField * _field; // 输入密码
 16     UILabel *_psw;        // 显示密码
 17 }
 18
 19 @end
 20
 21 @implementation ViewController
 22
 23 - (void)viewDidLoad {
 24     [super viewDidLoad];
 25
 26     self.view.backgroundColor = [UIColor whiteColor];
 27
 28     UILabel * labelName = [[UILabel alloc] initWithFrame:CGRectMake(0, 30, 100, 30)];
 29     labelName.text = @"密码是:";
 30
 31
 32     _field = [[UITextField alloc] initWithFrame:CGRectMake(100, 80, 200, 30)];
 33     _field.placeholder = @"请输入密码";
 34     _field.borderStyle = UITextBorderStyleRoundedRect;
 35
 36     _psw = [[UILabel alloc] initWithFrame:CGRectMake(100, 30, 200, 30)];
 37     _psw.backgroundColor = [UIColor yellowColor];
 38
 39     UIButton *btn = [UIButton buttonWithType:UIButtonTypeSystem];
 40     btn.frame =CGRectMake(100, 160, 200, 30);
 41     btn.backgroundColor = [UIColor colorWithRed:0 green:0.4 blue:0.1 alpha:0.8];
 42     btn.tintColor = [UIColor redColor];
 43     [btn setTitle:@"submit" forState:UIControlStateNormal];
 44     //[btn setTitle:@"正在提交" forState:UIControlStateSelected];
 45
 46     [btn addTarget:self action:@selector(btnClick:) forControlEvents:UIControlEventTouchUpInside];
 47 //    UIGestureRecognizer *tap = [[UIGestureRecognizer alloc] initWithTarget:self action:@selector(tap:)];
 48 //    [self.view addGestureRecognizer:tap];
 49
 50
 51
 52     [self.view addSubview:btn];
 53     [self.view addSubview:_field];
 54     [self.view addSubview:labelName];
 55     [self.view addSubview:_psw];
 56     // Do any additional setup after loading the view, typically from a nib.
 57 }
 58
 59 - (void)didReceiveMemoryWarning {
 60     [super didReceiveMemoryWarning];
 61     // Dispose of any resources that can be recreated.
 62 }
 63 //- (void)tap:(UIGestureRecognizer*)gr
 64 //{
 65 //
 66 //
 67 //    [_field resignFirstResponder];
 68 //}
 69
 70 - (void)btnClick:(id)sender
 71 {
 72     [ViewController savePassWord:_field.text];
 73     _psw.text = [ViewController readPassWord];
 74
 75     if (![_field isExclusiveTouch]) {
 76         //Setting this property to YES causes the receiver to block the delivery of touch events to other views in the same window. The default value of this property is NO.
 77         [_field resignFirstResponder];// 收回键盘
 78
 79     }
 80
 81 }
 82
 83 + (void)savePassWord:(NSString *)password
 84 {
 85     NSMutableDictionary *usernamepasswordKVPairs = [[NSMutableDictionary alloc] init];
 86     [usernamepasswordKVPairs setObject:password forKey:KEY_PASSWORD];
 87     [KeyChain save:KEY_IN_KEYCHAIN data:usernamepasswordKVPairs];
 88 }
 89
 90 + (id)readPassWord
 91 {
 92     NSMutableDictionary *usernamepasswordKVPairs = (NSMutableDictionary *)[KeyChain load:KEY_IN_KEYCHAIN];
 93
 94     return [usernamepasswordKVPairs objectForKey:KEY_PASSWORD];
 95
 96 }
 97
 98 + (void)deletePassWord
 99 {
100     [KeyChain delete:KEY_IN_KEYCHAIN];
101
102 }
103
104 @end

运行效果:

时间: 2024-09-20 20:42:53

简单实现KeyChain实例的相关文章

Python---BeautifulSoup 简单的爬虫实例

对python自动化比较熟的同学,很多都懂一些爬虫方法,有些还研究的很深,下面呢我介 绍一个简单的爬虫实例,供大家参考.当然里面有很多需求是可以再学习的,下载进度的显 示.下载完成的提示等等. 一.首先我们要研究爬虫网站的架构,我这里已ring.itools.cn为例,我需要爬的是铃声. 大家可以自己去分析,这个网站的架构比较简单就不讲了. 我们最终要获取的是下面两个信息: 二.我们写下面的脚本来获取 上面的脚本呢,获取到songname和playaddr都是一组数据,即都是列表,我们需要把 他

简单工程模式实例

前言 这几天做了一个应用程序,给项目添加的一个功能.一直想用什么模式来写,基本代码都写完了,还是没有用到模式,前天晚上睡觉中突然觉得就是简单工厂模式,于是代码已经浮现出来.昨天去了公司开始写. 过程 这是简单工厂类图:(图是从网上自己弄的) <大话设计模式>中,这个简单工厂模式,那个基接口是一个类,不是接口.我在写的时候也是写的是类.但是发现很多不可能实现.因为发现很多类,都有各自的字段属性,都不一样.所以没法用这个类,最后还是用了接口,感觉还是接口厉害,多态实现.工厂类跟基类接口的关系是依赖

【CentOS】一个简单的Expect实例详解

Expect是基于Tcl的相对简单的一个免费的基本变成工具语言,用于实现自动和交互式任务程序进行通信,无须人工干预. 一.Expect的安装检查与Linux系统的实验环境 1.Expect的安装 [[email protected]]# rpm -qa expect expect-5.43.0-8.el5 expect-5.43.0-8.el5 #如果未安装expect,可以通过yum进行安装 [[email protected]]# yum install expect -y 2.Linux的

ul、li列表简单实用代码实例

ul.li列表简单实用代码实例: 利用ul和li可以实现列表效果,下面就是一个简单的演示. 代码如下: <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="author" content="http://www.51texiao.cn/" /> <title>蚂蚁部落</title> &

Swift简单新闻APP实例

1.利用swift开发一个简单的新闻APP 主要利用IOS的UITableViewController,和UIwebView,再加上HTTP请求返回json数据并解析 2.APP演示 主界面 点击新闻进入详情 下拉列表刷新 3.APPDelegate.swif // // AppDelegate.swift // UITableViewControllerDemo // // Created by 赵超 on 14-6-24. // Copyright (c) 2014年 赵超. All rig

审核流(3)低调奢华,简单不凡,实例演示-SNF.WorkFlow--SNF快速开发平台3.1

下面我们就从什么都没有,结合审核流进行演示实例.从无到有如何快速完美的实现,然而如此简单.低调而奢华,简单而不凡. 从只有数据表通过SNF.CodeGenerator代码生成器快速生成单据并与审核流进行结合案例. 现在我只有这样一个表如下:(下面介绍单表,多表原理是一样的) 1.审核流结合代码生成器快速实现 1.用代码生成器生成单据(选择启用审核流) 之后点击“生成“并把对应代码拷贝到相应的位置,执行脚本把菜单预制进去,详见“06.SNF.CodeGenerator代码生成器使用说明.docx”

写一个最简单的gulp 实例

今天写了一个简单的gulp 实例 分享给大家! 比较适合gulp 初学者 首选: 看看gulp官网了解一些基本的定义 官网地址 : http://www.gulpjs.com.cn/ 搭建node环境 安装 gulp  自行百度吧! 文件目录 dist : 打包后文件所在目录 src : 源文件目录 glpfile.js : gulp的配置文件 package.json : 配置文件 安装依赖 : "devDependencies": { "colors": &qu

Android Service AIDL 远程调用服务 简单音乐播放实例的实现

Android Service是分为两种: 本地服务(Local Service): 同一个apk内被调用 远程服务(Remote Service):被另一个apk调用 远程服务需要借助AIDL来完成. AIDL 是什么 AIDL (Android Interface Definition Language) 是一种IDL 语言,用于生成可以在Android设备上两个进程之间进行进程间通信(interprocess communication, IPC)的代码.如果在一个进程中(例如Activi

Tstrings类简单介绍及实例

用TStrings保存文件;var  S: TStrings;begin  S := TStringList.Create();  { ... }  S.SaveToFile('config.txt', TEncoding.UTF8); Tstrings类简单介绍及实例 在DELPHI的程序开发过程中Tstrings类的使用是比较频繁的,下面就此类在DELPHI5的开发环境中进行一下简单的介绍及实例(注:本文只对tstrings类中的方法及属性进行介绍, 从其父类继承的属性及方法不属本文讨论之内