简单实现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];
//btn.layer.cornerRadius=8; 圆角
    //btn.layer.masksToBounds = YES;
   //btn.layer.borderWidth = 5;
    //btn.layer.borderColor=(__bridge CGColorRef)([UIColor redColor]);
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

运行效果:

转载于:https://www.cnblogs.com/liuziyu/p/4191332.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/259565.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

JAVA入门[6]-Mybatis简单示例

初次使用Mybatis,先手写一个hello world级别的例子&#xff0c;即根据id查询商品分类详情。 一、建表 create table Category ( Id INT not null, Name varchar(80) null, constraint pk_category primary key (Id) ); 插入测试数据 INSERT INTO category VALUES (1,Fish); INS…

ASP.NET MVC5 + EF6 入门教程 (6) View中的Razor使用

ASP.NET MVC5 EF6 入门教程 (6) View中的Razor使用 原文:ASP.NET MVC5 EF6 入门教程 (6) View中的Razor使用文章来源&#xff1a; Slark.NET-博客园 http://www.cnblogs.com/slark/p/mvc-5-ef-6-get-started-model.html 上一节&#xff1a;ASP.NET MVC5 EF6 入门教程 (5) M…

递归--基于回溯和递归的八皇后问题解法

八皇后问题是在8*8的棋盘上放置8枚皇后&#xff0c;使得棋盘中每个纵向、横向、左上至右下斜向、右上至左下斜向均只有一枚皇后。八皇后的一个可行解如图所示&#xff1a; 思路 对于八皇后的求解可采用回溯算法&#xff0c;从上至下依次在每一行放置皇后&#xff0c;进行搜索&a…

matlab emf 读取,20140219-Emf_Demo EMF 矢量图 可以读取和保存EMF 的封闭类 非常实用 matlab 238万源代码下载- www.pudn.com...

文件名称: 20140219-Emf_Demo下载收藏√ [5 4 3 2 1 ]开发工具: Visual C文件大小: 6312 KB上传时间: 2014-07-10下载次数: 2详细说明&#xff1a;EMF 矢量图 可以读取和保存EMF矢量图的封闭类非常实用-EMF EMF vector can read and save the class very useful vector cl…

JS中popup.js

为什么80%的码农都做不了架构师&#xff1f;>>> //popup class 显示弹出窗口&#xff0c;。/*以下为使用popup对象&#xff0c;传入相应的配置参数&#xff0c;弹出不同类型的窗口 function ShowIframe() //显示iframe { var popnew P…

二阶振荡衰减 matlab,基于Matlab/Simulink的二阶控制系统仿真研究

1 二阶控制系统模型本文引用地址&#xff1a;http://www.eepw.com.cn/article/201612/328597.htm能够用二阶微分方程描述的系统称为二阶控制系统。在控制工程实践中&#xff0c;二阶控制系统十分常见&#xff0c;例如&#xff0c;电枢控制的直流电动机&#xff0c;RLC网络和弹簧…

CCF201409-5 拼图(30分)

试题编号&#xff1a; 201409-5 试题名称&#xff1a; 拼图 时间限制&#xff1a; 3.0s 内存限制&#xff1a; 256.0MB 问题描述&#xff1a; 问题描述给出一个nm的方格图&#xff0c;现在要用如下L型的积木拼到这个图中&#xff0c;使得方格图正好被拼满&#xff0c;请问总共有…

C++ 0x

转载于:https://www.cnblogs.com/iiiDragon/p/3230006.html

Github for Windows使用介绍

Git已经变得非常流行&#xff0c;连Codeplex现在也已经主推Git。Github上更是充斥着各种高质量的开源项目&#xff0c;比如ruby on rails&#xff0c;cocos2d等等。对于习惯Windows图形界面的程序员来讲&#xff0c;Github的使用是需要点时间和耐心的&#xff0c;然而最近Githu…

matlab中udt函数,《MATLAB信号处理超级学习手册》——2.5 离散时间信号中的运算...

本节书摘来自异步社区《MATLAB信号处理超级学习手册》一书中的第2章&#xff0c;第2.5节&#xff0c;作者&#xff1a;MATLAB技术联盟 , 史洁玉著&#xff0c;更多章节内容可以访问云栖社区“异步社区”公众号查看2.5 离散时间信号中的运算MATLAB信号处理超级学习手册2.5.1 离散…

构建Docker镜像(三)

作者:李晓辉联系方式:Xiaohui_lifoxmail.comQQ:939958092一、建立Dockerfile1、准备文件新建一个目录和一个 Dockerfilemkdir /steventouch /steven/Dockerfile2、更新Dockerfile这个步骤是在设计镜像&#xff0c;如果你需要在镜像内包含什么软件&#xff0c;将来开放哪些端口&…

你必须很努力,才能看上去毫不费力

世上没有一件工作不辛苦&#xff0c;没有一处人事不复杂。 从今天起&#xff0c;每天微笑吧&#xff0c; 世上除了生死&#xff0c;都是小事。 不管遇到了什么烦心事&#xff0c;都不要自己为难自己&#xff1b; 无论今天发生多么糟糕的事&#xff0c;都不应该感到悲伤。 今天是…

HDU 4631 Sad Love Story 平面内最近点对

http://acm.hdu.edu.cn/showproblem.php?pid4631 题意: 在平面内依次加点,求每次加点后最近点对距离平方的和 因为是找平面最近点对...所以加点以后这个最短距离一定是递减的...所以最后会形成这样一个函数图像 所以我们只要从后往前依次删点即可... 15秒惊险水过...不过我最小…

itoa的用法

功能&#xff1a;将任意类型的整数转换为字符串。在<stdlib.h>中与之有相反功能的函数是atoi。 用法&#xff1a;char*itoa(int value,char*string,int radix); int value 被转换的整数&#xff0c;char *string 转换后储存的字符数组&#xff0c;int radix 转换进制数…

Tomcat与Gzip与缓存

国内私募机构九鼎控股打造APP&#xff0c;来就送 20元现金领取地址&#xff1a;http://jdb.jiudingcapital.com/phone.html内部邀请码&#xff1a;C8E245J &#xff08;不写邀请码&#xff0c;没有现金送&#xff09;国内私募机构九鼎控股打造&#xff0c;九鼎投资是在全国股份…

java竖向菜单,垂直滑动菜单

www.lanrentuku.comtd {font-size: 12px;}width"200" />height9 src"images/bit05.gif" width8alignabsMiddle> href"javascript:void(null)">文管产品 src"images/bit06.gif" width8 alignabsMiddle> href"http://w…

[转]第一章 Windows Shell是什么 【来源:http://blog.csdn.net/wangqiulin123456/article/details/7987862】...

一个操作系统外壳的不错的定义是它是一个系统提供的用户界面&#xff0c;它允许用户执行公共的任务&#xff0c;如访问文件系统&#xff0c;导出执行程序&#xff0c;改变系统设置等。MS-DOS有一个Command.COM扮演着这个角色。然而Windows已经有了图形界面环境&#xff0c;他的…

20155222卢梓杰 《Java程序设计》第1周学习总结

20155222 《Java程序设计》第1周学习总结 教材学习内容总结 JDK是一个工具程序&#xff0c;包括了JAVA程序语言&#xff0c;工具程序与JRE&#xff0c;JRE包括了部署技术&#xff0c;JAVA SE API 与 JVM。 教材学习中的问题和解决过程 第一章&#xff1a;JDK的变量和选项如何设…

DateTime.Now.ToString() 用法

//2008年4月24日 System.DateTime.Now.ToString("D"); //2008-4-24 System.DateTime.Now.ToString("d"); //2008年4月24日 16:30:15 System.DateTime.Now.ToString("F"); //2008年4月24日 16:30 System.DateTime.No…

GAP平台

2019独角兽企业重金招聘Python工程师标准>>> 转载于:https://my.oschina.net/u/2441327/blog/846754