IOS KeyChain理解及代码事例

对KeyChain的理解,可参照http://my.oschina.net/w11h22j33/blog/206713

文中利用KeyChain保存用户名和密码,用户名放在属性中,密码放在密码项中;其中对KeyChain项的增删改查,我个人觉得是有问题的,为了方面自己代码上的使用,也帮助阅读该文的其他读者更好的理解,我修正了代码如下:

//存储/增加
-(IBAction)saveClicked:(id)sender{

    if(_nameTF.text.length > 0 && _psdTF.text.length > 0) {
        NSMutableDictionary* dic = [NSMutableDictionary dictionary];

        [dic setObject:(__bridge_transfer id)kSecClassGenericPassword forKey:(__bridge_transfer id)kSecClass];
        [dic setObject:_nameTF.text forKey:(__bridge_transfer id)kSecAttrAccount];
        [dic setObject:[_psdTF.text dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge_transfer id)kSecValueData];

        OSStatus s = SecItemAdd((__bridge_retained CFDictionaryRef)dic, NULL);
        NSLog(@"%d",s);
    }

}

//获取/查询
-(IBAction)showClicked:(id)sender
{
    if(_nameTF.text.length > 0) {
        NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:
                               (__bridge_transfer id)kSecClassGenericPassword, (__bridge_transfer id)kSecClass,
                               _nameTF.text, (__bridge_transfer id)kSecAttrAccount,
                               kCFBooleanTrue, kSecReturnAttributes,nil];

        CFTypeRef result = nil;
        OSStatus s = SecItemCopyMatching((__bridge_retained CFDictionaryRef)query, &result);

        NSLog(@"%d",s);
        NSLog(@"%@",result);

        if(s == noErr) {//通过用户判断item项是否存在
            NSMutableDictionary* dic = [NSMutableDictionary dictionaryWithDictionary:(__bridge_transfer id)result];
            [dic setObject:(__bridge_transfer id)kCFBooleanTrue forKey:(__bridge_transfer id)kSecReturnData];
            [dic setObject:[query objectForKey:(__bridge_transfer id)kSecClass] forKey:(__bridge_transfer id)kSecClass];

            CFDataRef dataRef = NULL;

            if(SecItemCopyMatching((__bridge_retained CFDictionaryRef)dic, (CFTypeRef*)&dataRef) == noErr) {

                NSData *data = (__bridge_transfer id)dataRef;
                NSLog(@"%ld", data.length);

                NSLog(@"%@",[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
            }
        }
    }else{

        NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:
                               (__bridge_transfer id)kSecClassGenericPassword,(__bridge_transfer id)kSecClass,
                               (__bridge_transfer id)kSecMatchLimitAll, (__bridge_transfer id)kSecMatchLimit,
                               (__bridge_transfer id)kCFBooleanTrue,(__bridge_transfer id)kSecReturnAttributes,nil];

        CFArrayRef result = NULL;
        OSStatus s = SecItemCopyMatching((__bridge_retained CFDictionaryRef)query, (CFTypeRef*)&result);

        NSArray *array = (__bridge_transfer NSArray*)result;//(可以遍历所有keychain项)

        NSLog(@"%d",s);
        NSLog(@"%@",result);
    }

}

//删除
-(IBAction)delClicked:(id)sender{

    if(_nameTF.text.length > 0){
        NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:(__bridge_transfer id)kSecClassGenericPassword,kSecClass,
                               _nameTF.text,kSecAttrAccount,nil];
        OSStatus status = SecItemDelete((__bridge_retained CFDictionaryRef)query);
        NSLog(@"%d",status);
    }

}

//改
-(IBAction)modifyClicked:(id)sender{

    if(_nameTF.text.length > 0 && _psdTF.text.length > 0) {
        NSDictionary* query = [NSDictionary dictionaryWithObjectsAndKeys:
                               (__bridge_transfer id)kSecClassGenericPassword, (__bridge_transfer id)kSecClass,
                               _nameTF.text, (__bridge_transfer id)kSecAttrAccount,
                               (__bridge_transfer id)kCFBooleanTrue, (__bridge_transfer id)kSecReturnAttributes,nil];

        CFTypeRef result = nil;
        if(SecItemCopyMatching((__bridge_retained CFDictionaryRef)query, &result) == noErr)//存在才修改
        {
            //设置需要更新的属性列表,一定要删除kSecClass,因为不能update不该字段,否则会报错
            NSMutableDictionary* update = [[NSMutableDictionary alloc]init];
            [update setObject:[_psdTF.text dataUsingEncoding:NSUTF8StringEncoding] forKey:(__bridge_transfer id)kSecValueData];
            [update removeObjectForKey:(__bridge_transfer id)kSecClass];

            //设置查找条件,即根据这个条件找到keychain项
            NSMutableDictionary* updateItem = [[NSMutableDictionary alloc]init];
            [updateItem setObject:[query objectForKey:(__bridge_transfer id)kSecClass] forKey:(__bridge_transfer id)kSecClass];
            [updateItem setObject:_nameTF.text forKey:(__bridge_transfer id)kSecAttrAccount];

            //参数一表示要查虚的,参数二表示更新后的值
            OSStatus status = SecItemUpdate((__bridge_retained CFDictionaryRef)updateItem, (__bridge_retained CFDictionaryRef)update);
            NSLog(@"%d",status);
        }
    }
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-11-15 22:25:25

IOS KeyChain理解及代码事例的相关文章

iOS_SN_BlueTooth (二)iOS 连接外设的代码实现

原文:http://www.cocoachina.com/ios/20150917/13456.html?utm_source=tuicool&utm_medium=referral 上一篇文章介绍了蓝牙的技术知识,这里我们具体说明一下中心模式的应用场景.主设备(手机去扫描连接外设,发现外设服务和属性,操作服务和属性的应用.一般来说,外设(蓝牙设备,比如智能手环之类的东西),会由硬件工程师开发好,并定义好设备提供的服务,每个服务对于的特征,每个特征的属性(只读,只写,通知等等),本文例子的业务场

[iOS笔记]《编写高质量iOS与OS X代码的52个有效方法》:1.熟悉Objective-C

简介: 最近公司项目收尾,可以有时间看看书了.<编写高质量iOS与OS X代码的52个有效方法>这本书讲解了很多iOS开发的技巧和规范,大力推荐! 下面是自己看书时整理的笔记,照惯例先上目录: 目录: 第一章:熟悉Objective-C 第二章:Object.Message.Runtime 第三章:接口与API设计 第四章:Protocol与Category 第五章:内存管理 第六章:Block与GCD 第七章:系统框架 第一章    熟悉Objective-C 第1条:了解Objective

iOS开发中的那些的约定俗成(1)————《编写高质量iOS与OS X代码的52个有效方法》读书笔记(第一章)

iOS开发中的那些的约定俗成(1) ----<编写高质量iOS与OS X代码的52个有效方法>读书笔记(第一章) 前言 "我要成为一个高产的开发人员.""想要混的好,就得多努力." 写这些东西是因为毕竟看了书,但是看书看过去之后,也许印象不是很深刻,有些东西现在也理解不了,那我就把我理解的,现在就可以用到的东西,简单的写出来就好,让自己今后看到就能明白其中的意思. 还有就是锻炼一下表达,编辑能力,慢慢的提升自己,随时随地的都要有一个锻炼的心. 最后当然就

iOS书写高质量代码之耦合的处理 干货!

iOS书写高质量代码之耦合的处理 耦合是每个程序员都必须面对的话题,也是容易被忽视的存在,怎么处理耦合关系到我们最后的代码质量.今天Peak君和大家聊聊耦合这个基本功话题,一起捋一捋iOS代码中处理耦合的种种方式及差异. 简化场景 耦合的话题可大可小,但原理都是相通的.为了方便讨论,我们先将场景进行抽象和简化,只讨论两个类之间的耦合. 假设我们有个类Person,需要喝水,根据职责划分,我们需要另一个类Cup来完成喝水的动作,代码如下: 1 2 3 4 5 6 7 8 9 //Person.h

iOS 编译含C++代码出现ld: symbol(s) not found for architecture i386错误之解决(转载)

最近项目需要搭建自己的IM服务器,在快速配置好Openfire之后,开始研究使用gloox开发XMPP客户端实现通信, 先下载gloox源码,然后./configure,make ,sudo make install,在/usr/local/下找到头文件夹和静态库,加到项目中,然后加入openssl库,编写测试代码,编译,报错:XXX not being for architecture i386,感觉是gloox静态库有问题(排除了网上说的头文件路径缺失.building phases没添加.

ios图片瀑布流代码

ios瀑布流,实现简单的瀑布流视图布局,可以显示网络图片,下拉刷新,上拉加载更多. 下载:http://www.huiyi8.com/sc/9087.html ios图片瀑布流代码,布布扣,bubuko.com

iOS Keychain 跨应用

Keychain 可以用来持久保存一些信息.通常每个应用都有自己的 Keychain Access.但有时你会需要多个应用共用一些信息.这时需要创建 Keychain Access Group. Keychain Access Group 需要在 entitlements 文件里创建.值默认是 AppIdentifierPrefix+项目 id.前者是 AppId 的前缀,对于每个开发者,这个是唯一的.我们把项目 id 改为一个新起的组名.最后它的样子应该是这样:$(AppIdentifierP

ios 使用xcode调试代码的时候进入断点显示变量全是nil,但NSLog输出那个变量却是有值的

解决办法:把1删掉 2选择debug模式 ios 使用xcode调试代码的时候进入断点显示变量全是nil,但NSLog输出那个变量却是有值的,布布扣,bubuko.com

[ios源码] 仿闲鱼二手交易平台-iOS源码-捡代码论坛

仿闲鱼二手交易平台-iOS源码-捡代码论坛 添加 首页模块和我的模块 首页水平滑动图利用自定义UICollectionViewFlowLayout实现 利用KVC,基于系统自带tabBar的进行定制实现底部TabBar. 页面跳转转场动画效果 封装刷新控件,仿闲鱼动画效果 动图演示(5.4M): Tag:闲鱼,iOS,动画,UICollectionView,视图布局 下载地址: 仿闲鱼二手交易平台-iOS源码-捡代码论坛http://bbs.jiandaima.com/thread-714-1-