Keychain introduction and use

What is the Keychain?

the iOS keychain service provides a secure hold of private information (passwords, serial numbers, certificates, etc.) the way, ios each program has a separate keychain storage.
Some used to store private information, such as passwords, certificates, etc., Keychain in App saved information will not be deleted and lost, it is still valid after the user to re-install the App.
The same applies to data sharing between applications. We can KeyChain understood as a Dictionary, with all the data in the form of key-value store, you can add, update, get, delete these four operations on the Dictionary.

Keychain four methods of presentation?

Storage method

OSStatus SecItemAdd(CFDictionaryRef attributes, CFTypeRef * __nullable CF_RETURNS_RETAINED result)
复制代码

attributes: To add the data
result: After storing the data and returns a reference to the data, do not use this data into nil

Conditions query methods

OSStatus SecItemCopyMatching(CFDictionaryRef query, CFTypeRef * __nullable CF_RETURNS_RETAINED result)
复制代码

query: conditions to query data
result: the query to reference data

Method for updating data

OSStatus SecItemUpdate(CFDictionaryRef query, CFDictionaryRef attributesToUpdate)
复制代码

query: To update the data query
attributesToUpdate: data to be updated

Deleting Data Methods

OSStatus SecItemDelete(CFDictionaryRef query)
复制代码

query: query the data to be deleted

Use Keychain

Use Keychain First you need to import security framework secutity.framework

Create a query

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
}
复制代码

Storing data

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
}
复制代码

update data

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
}
复制代码

Query data

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
}
复制代码

delete data

class func keyChianDelete(identifier: String)->Void{
    // 获取删除的条件
    let keyChainDeleteMutableDictionary = self.createQuaryMutableDictionary(identifier: identifier)
    // 删除数据
    SecItemDelete(keyChainDeleteMutableDictionary)
}
复制代码

Simple application

Get UUID

Direct access UUID each time after unloading reinstall the app may cause the UUID changes, in order to obtain a unique UUID, we use keyChian to save UUID

class func getUUID() -> String {
    if let uuid = QWUUIDTools.keyChainReadData(identifier: "key") as? String {
        return uuid
    }else {
        if let uuid = UIDevice.current.identifierForVendor?.uuidString {
            if QWUUIDTools.keyChainSaveData(data: uuid, withIdentifier: "key") {
                return uuid
            }
        }
    }
    return "simulator"
}
复制代码

Guess you like

Origin blog.csdn.net/weixin_33910137/article/details/91374812