引言
App的开发中,用户登录的模块是必不可少的。用户登录一次之后,就可以使用自动登录功能。自动登录需要知道用户的账号和密码。那么用户的账户和密码是保密性的,为实现App的自动登录功能,我们要稳妥的管理好用户的账号和密码的安全。所以 Keychain 就被使用的上了。下面将给你介绍 Keychain 是什么、如何使用等。友情链接:Object-C 版的密码管理 Keychain 的连接地址 iOS的密码管理系统 Keychain的介绍和使用。
Keychain 是什么?
Keychain 是苹果公司 Mac OS(也包含 Mac OSX) 中的密码管理系统。
Keychain 的作用是什么?
Keychain 可以包含许多种类型的数据:密码(包括网站、FTP服务器、SSH账户、网络共享、无线网络、群组软件、加密磁盘镜像),私钥,电子证书、加密笔记等。
Keychain 的四个方法的介绍
1、数据的存储方法
@available(iOS 2.0, *)
public func SecItemAdd(_ attributes: CFDictionary, _ result: UnsafeMutablePointer<CoreFoundation.CFTypeRef?>?) -> OSStatus
@ attributes : 要存储的数据。
@ result : 存储数据后,返回的指向该数据的引用。
2、根据查询条件获取数据
@available(iOS 2.0, *)
public func SecItemCopyMatching(_ query: CFDictionary, _ result: UnsafeMutablePointer<CoreFoundation.CFTypeRef?>?) -> OSStatus
@ query : 获取数据的查询条件。
@ result : 查询后获取到数据的引用。
3、更新数据
@available(iOS 2.0, *)
public func SecItemUpdate(_ query: CFDictionary, _ attributesToUpdate: CFDictionary) -> OSStatus
@ query : 要更新数据的查询条件。
@ attributesToUpdate : 要更新的数据内容。
4、删除数据
@available(iOS 2.0, *)
public func SecItemDelete(_ query: CFDictionary) -> OSStatus
@ query : 删除数据的查询条件。
总结,以上四个方法,就是 Keychain 的增、删、改、查的四个基本方法。这四个方法基本满足大部分App的使用需求。
Keychain 的整理和封装为一个类: KeychainManager.swift 。
KeychainManager.swift 的完整代码展示:
//
// KeychainManager.swift
// KeyChain
//
// Created by MAC on 2017/11/20.
// Copyright © 2017年 NetworkCode小贱. All rights reserved.
//
import UIKit
class KeychainManager: NSObject {
// TODO: 创建查询条件
class func createQuaryMutableDictionary(identifier:String)->NSMutableDictionary{
// 创建一个条件字典
let keychainQuaryMutableDictionary = NSMutableDictionary.init(capacity: 0)
// 设置条件存储的类型
keychainQuaryMutableDictionary.setValue(kSecClassGenericPassword, forKey: kSecClass as String)
// 设置存储数据的标记
keychainQuaryMutableDictionary.setValue(identifier, forKey: kSecAttrService as String)
keychainQuaryMutableDictionary.setValue(identifier, forKey: kSecAttrAccount as String)
// 设置数据访问属性
keychainQuaryMutableDictionary.setValue(kSecAttrAccessibleAfterFirstUnlock, forKey: kSecAttrAccessible as String)
// 返回创建条件字典
return keychainQuaryMutableDictionary
}
// TODO: 存储数据
class func keyChainSaveData(data:Any ,withIdentifier identifier:String)->Bool {
// 获取存储数据的条件
let keyChainSaveMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
// 删除旧的存储数据
SecItemDelete(keyChainSaveMutableDictionary)
// 设置数据
keyChainSaveMutableDictionary.setValue(NSKeyedArchiver.archivedData(withRootObject: data), forKey: kSecValueData as String)
// 进行存储数据
let saveState = SecItemAdd(keyChainSaveMutableDictionary, nil)
if saveState == noErr {
return true
}
return false
}
// TODO: 更新数据
class func keyChainUpdata(data:Any ,withIdentifier identifier:String)->Bool {
// 获取更新的条件
let keyChainUpdataMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
// 创建数据存储字典
let updataMutableDictionary = NSMutableDictionary.init(capacity: 0)
// 设置数据
updataMutableDictionary.setValue(NSKeyedArchiver.archivedData(withRootObject: data), forKey: kSecValueData as String)
// 更新数据
let updataStatus = SecItemUpdate(keyChainUpdataMutableDictionary, updataMutableDictionary)
if updataStatus == noErr {
return true
}
return false
}
// TODO: 获取数据
class func keyChainReadData(identifier:String)-> Any {
var idObject:Any?
// 获取查询条件
let keyChainReadmutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
// 提供查询数据的两个必要参数
keyChainReadmutableDictionary.setValue(kCFBooleanTrue, forKey: kSecReturnData as String)
keyChainReadmutableDictionary.setValue(kSecMatchLimitOne, forKey: kSecMatchLimit as String)
// 创建获取数据的引用
var queryResult: AnyObject?
// 通过查询是否存储在数据
let readStatus = withUnsafeMutablePointer(to: &queryResult) { SecItemCopyMatching(keyChainReadmutableDictionary, UnsafeMutablePointer($0))}
if readStatus == errSecSuccess {
if let data = queryResult as! NSData? {
idObject = NSKeyedUnarchiver.unarchiveObject(with: data as Data) as Any
}
}
return idObject as Any
}
// TODO: 删除数据
class func keyChianDelete(identifier:String)->Void{
// 获取删除的条件
let keyChainDeleteMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
// 删除数据
SecItemDelete(keyChainDeleteMutableDictionary)
}
}
上面展示的代码已经注释非常详细了,就不在多介绍了。如果还有不了解的地方可以查看iOS版本的Keychain,连接如下:iOS的密码管理系统 Keychain的介绍和使用。
KeychainManager.swift 类的测试和使用
1、测试代码
// 存储数据
let saveBool = KeychainManager.keyChainSaveData(data: "我期待的女孩" as Any, withIdentifier: KeyChain)
if saveBool {
print("存储成功")
}else{
print("存储失败")
}
// 获取数据
let getString = KeychainManager.keyChainReadData(identifier: KeyChain) as! String
print(getString)
// 更新数据
let updataBool = KeychainManager.keyChainUpdata(data: "眼睛像云朵", withIdentifier: KeyChain)
if updataBool {
print("更新成功")
}else{
print("更新失败")
}
// 获取更新后的数据
let getUpdataString = KeychainManager.keyChainReadData(identifier: KeyChain) as! String
print(getUpdataString)
// 删除数据
KeychainManager.keyChianDelete(identifier: KeyChain)
// 获取删除后的数据
let getDeleteString = KeychainManager.keyChainReadData(identifier: KeyChain)
print(getDeleteString)
2、测试结果的展示
下载Demo 的方法
- 联系简主 m: 18801210281 q:1542100658
- 加入群:185341804
- email : zhoushaungjian511@163.com