iOS 資料持久化之KeyChain(Swift Demo),ioskeychain

來源:互聯網
上載者:User

iOS 資料持久化之KeyChain(Swift Demo),ioskeychain

原創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沒有顯示黑點,是為了方便查看。

四種操作
---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 Securityclass 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")        }    }
總結

簡單來講,一共就是四個函數

歡迎關注我的iOS詳解專欄,這裡我會講解絕大部分iOS常用的技術
http://blog.csdn.net/column/details/huangwenchen-ios-sdk.html
我的部落格iOS部分目錄
http://blog.csdn.net/hello_hwc/article/details/45365385

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.