iOS 数据持久化之KeyChain(Swift Demo)
2015-05-05 15:34
363 查看
原创blog,转载请注明出处
blog.csdn.net/hello_hwc?viewmode=list
前言:前两篇持久化分别讲到了
NSUserDefaults保存Settings信息
Plist保存简单的结构化信息
本文讲解如何保存需要加密的信息。绝大多数情况下都是保存密码。少数情况下需要保存证书等信息。本文以密码为例,讲解如何用iOS SDK原生API来进行KeyChain的操作。
实际开发的过程中,建议使用一些Github的集成库,或者自己写一个KeyChain的库,很简单
源代码提供Swift版本,完整工程下载
CSDN下载
http://download.csdn.net/detail/hello_hwc/8663811
GitHub
https://github.com/wenchenhuang/SwiftKeyChainDemo
Demo效果
四个按键对应添加,更新,获取,删除
Demo的password没有显示黑点,是为了方便查看。
四种操作
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/25/c83af28f94f574ee6ad0a74471b94feb)
---Get----
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/25/6252c1699e3294889009267467396f5c)
注意:keyChain的访问权限依赖于provisioning file。所以,如果要在应用更新的时候,仍然能够访问之前保存的密码,要保证provisioning file是同一个文件。
一个典型的字典
![](https://oscdn.geek-share.com/Uploads/Images/Content/202011/25/738efac04773453c352edbfa874f3cb4)
其中
kSecClass 表示存储的是密码
kSecAttrAccount 表示的是为IamUser这个账号存储的密码
kSecAttrService 表示是为App Store存储的账号
其余两个在查询的时候使用,知道如果要查询都设为ture就可以了
所有的keys可以从以下链接获取
https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html
用UIAlertController提示信息
kSecValueData这个key是实际要保存的密码,要先转换成NSData
SecItemAdd这个函数来添加keyChain,返回值是OSStatus类型,错误类型较多,可以Google。这里知道0是没有错误就可以了。
SecItemCopyMatching - 查询和获取
SecItemUpdate - 更新
SecItemAdd - 添加
SecItemDelete - 删除
欢迎关注我的iOS详解专栏,这里我会讲解绝大部分iOS常用的技术
http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html
我的博客iOS部分目录
/article/1511826.html
blog.csdn.net/hello_hwc?viewmode=list
前言:前两篇持久化分别讲到了
NSUserDefaults保存Settings信息
Plist保存简单的结构化信息
本文讲解如何保存需要加密的信息。绝大多数情况下都是保存密码。少数情况下需要保存证书等信息。本文以密码为例,讲解如何用iOS SDK原生API来进行KeyChain的操作。
实际开发的过程中,建议使用一些Github的集成库,或者自己写一个KeyChain的库,很简单
源代码提供Swift版本,完整工程下载
CSDN下载
http://download.csdn.net/detail/hello_hwc/8663811
GitHub
https://github.com/wenchenhuang/SwiftKeyChainDemo
Demo效果
四个按键对应添加,更新,获取,删除
Demo的password没有显示黑点,是为了方便查看。
四种操作
---Get----
KeyChain简介
KeyChain是一个加密的容器,通常用来保存密码,证书,和一些需要加密的key。对于iOS来说,每个App有独立的keyChain,每个app只能访问自己的keyChain.注意:keyChain的访问权限依赖于provisioning file。所以,如果要在应用更新的时候,仍然能够访问之前保存的密码,要保证provisioning file是同一个文件。
KeyChain描述
keyChain是通过字典来描述的,是一组key-value的对。用来描述这个keyChain是为什么样的应用保存什么样的数据,有什么样的访问权限等等。一个典型的字典
其中
kSecClass 表示存储的是密码
kSecAttrAccount 表示的是为IamUser这个账号存储的密码
kSecAttrService 表示是为App Store存储的账号
其余两个在查询的时候使用,知道如果要查询都设为ture就可以了
所有的keys可以从以下链接获取
https://developer.apple.com/library/ios/documentation/Security/Reference/keychainservices/index.html
手把手教你建立Demo App
创建一个基于Swift的工程,然后在storyboard上拖拽控件
并且拖拽outlet和action,然后实现UITextFieldDelegate,保证我们点击Return的时候,键盘会消失。这时候的代码如下import Security class ViewController: UIViewController,UITextFieldDelegate{ @IBOutlet weak var usernameTextfield: UITextField! @IBOutlet weak var passwordTextField: UITextField! @IBAction func addKeyChainItem(sender: AnyObject) { } @IBAction func updateKeyChainItem(sender: AnyObject) { } @IBAction func getKeyChainItem(sender: AnyObject) { } @IBAction func deleteKeyChainItem(sender: AnyObject) { } override func viewDidLoad() { super.viewDidLoad() usernameTextfield.delegate = self passwordTextField.delegate = self // Do any additional setup after loading the view, typically from a nib. } func textFieldShouldReturn(textField: UITextField) -> Bool { textField.resignFirstResponder() return true } }
然后,添加几个个辅助方法,减少我们的代码量
创建默认的描述字典func createDefaultKeyChainItemDic()->NSMutableDictionary{ var keyChainItem = NSMutableDictionary() keyChainItem.setObject(kSecClassInternetPassword as NSString, forKey: kSecClass as NSString) keyChainItem.setObject("blog.csdn.net/hello_hwc", forKey: kSecAttrServer as NSString) keyChainItem.setObject(self.usernameTextfield.text, forKey: kSecAttrAccount as NSString) return keyChainItem }
用UIAlertController提示信息
func alertWithMessage(message:String){ var alertController = UIAlertController(title:"Info", message: message, preferredStyle: UIAlertControllerStyle.Alert) alertController.addAction(UIAlertAction(title:"OK", style: UIAlertActionStyle.Cancel, handler:nil)) self.presentViewController(alertController, animated: true, completion: nil) } func alertWithStatus(status:OSStatus){ if(status == 0){ self.alertWithMessage("Success") }else{ self.alertWithMessage("Fail ErrorCode is\(status)") } }
添加KeyChain
这里用函数SecItemCopyMatching来查找这个keyChain是否存在。两个参数,第一个是描述字典,第二个是查找结果拷贝到的字典,通常只有在获取的时候才会用到,这里为nil即可。kSecValueData这个key是实际要保存的密码,要先转换成NSData
SecItemAdd这个函数来添加keyChain,返回值是OSStatus类型,错误类型较多,可以Google。这里知道0是没有错误就可以了。
@IBAction func addKeyChainItem(sender: AnyObject) { var keyChainItem = self.createDefaultKeyChainItemDic() if SecItemCopyMatching(keyChainItem,nil) == noErr{ self.alertWithMessage("User name already exits") }else{ keyChainItem.setObject(self.passwordTextField.text.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:true)!, forKey: kSecValueData as String) var status = SecItemAdd(keyChainItem, nil) self.alertWithStatus(status) } }
更新KeyChain
SecItemUpdate函数用来更新KeyChain,两个参数,第一个参数是描述字典,第二个是包含更新数据的字典@IBAction func updateKeyChainItem(sender: AnyObject) { var keyChainItem = self.createDefaultKeyChainItemDic() if SecItemCopyMatching(keyChainItem,nil) == noErr{ var updateDictionary = NSMutableDictionary() updateDictionary.setObject(self.passwordTextField.text.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:true)!, forKey:kSecValueData as String) var status = SecItemUpdate(keyChainItem,updateDictionary) self.alertWithStatus(status) }else{ self.alertWithMessage("The keychain doesnot exist") } }
删除keyChain
SecItemDelete函数用来删除@IBAction func deleteKeyChainItem(sender: AnyObject) { var keyChainItem = self.createDefaultKeyChainItemDic() if SecItemCopyMatching(keyChainItem,nil) == noErr{ let status = SecItemDelete(keyChainItem) self.alertWithStatus(status) }else{ self.alertWithMessage("The keychain doesnot exist") } }
获取KeyChain
SecItemCopyMatching第二个参数包含了获取到的字典信息。转换方式有点复杂。@IBAction func getKeyChainItem(sender: AnyObject) { var keyChainItem = self.createDefaultKeyChainItemDic() keyChainItem.setObject(kCFBooleanTrue, forKey: kSecReturnData as String) keyChainItem.setObject(kCFBooleanTrue, forKey: kSecReturnAttributes as String) var queryResult: Unmanaged<AnyObject>? let status = SecItemCopyMatching(keyChainItem,&queryResult) let opaque = queryResult?.toOpaque() var contentsOfKeychain: NSString? if let op = opaque { let retrievedData = Unmanaged<NSDictionary>.fromOpaque(op).takeUnretainedValue() let passwordData = retrievedData.objectForKey(kSecValueData) as! NSData let passwordString = NSString(data: passwordData, encoding: NSUTF8StringEncoding)! self.alertWithMessage("Password: \(passwordString)") }else{ self.alertWithMessage("The keychain doesnot exist") } }
总结
简单来讲,一共就是四个函数SecItemCopyMatching - 查询和获取
SecItemUpdate - 更新
SecItemAdd - 添加
SecItemDelete - 删除
欢迎关注我的iOS详解专栏,这里我会讲解绝大部分iOS常用的技术
http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html
我的博客iOS部分目录
/article/1511826.html
相关文章推荐
- iOS 数据持久化之CoreData(二)堆栈建立和基本操作Demo
- iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver
- iOS开发笔记-swift实现iOS数据持久化之归档NSKeyedArchiver
- iOS 使用字典NSMutableDictionary保存数据到文件(持久化)~ Swift
- ios开发学习笔记--数据持久化之数据库(SQLite.swift)
- iOS(Swift)使用字典NSMutableDictionary保存数据到文件(持久化)
- IOS——使用keychain对数据进行持久化保存(删除APP不影响数据)
- iOS应用开发之Core Data数据持久化存储笔记
- iOS开发中的本地数据存储(持久化)
- iOS项目开发实战(Swift)—View之间传递数据
- iOS 数据持久化一-属性列表 Plist
- iOS 数据持久化之plist
- ios学习记录 day36 UI12初级数据持久化(沙盒)
- iOS用户数据安全:Keychain、Touch ID以及1Password
- iOS 数据的持久化存储
- ios开发之数据的持久化存储机制
- iOS网络编程4--使用SwiftyJSON解析JSON数据
- ios开发学习----swift学习之(一)基础数据类型
- ios数据持久化-属性列表NSUserDefaults、对象归档NSKeyedArchiver和NSKeyedUnarchive、嵌入式数据库(SQLite3)