美文网首页
iOS Swift用keychain保存用户名和密码

iOS Swift用keychain保存用户名和密码

作者: Lee坚武 | 来源:发表于2022-04-14 15:57 被阅读0次

    本人亲测有效!绝对可靠!更多交流可以家魏鑫:lixiaowu1129,一起探讨iOS相关技术!

    工具类一

    import UIKit
    import Security
    
    public class HTKeychainManager: NSObject {
        
        public static let instance :HTKeychainManager = {
            let instance = HTKeychainManager();
            return instance;
        }()
        
        public class func save(server:String,account:String,password:String)->Bool{
            var dictionry:Dictionary = Dictionary<String, Any>()
            
            dictionry.updateValue(server, forKey: kSecAttrServer as String)
            dictionry.updateValue(account, forKey: kSecAttrAccount as String)
            
            dictionry.updateValue(kSecClassInternetPassword, forKey: kSecClass as String)
            dictionry.updateValue(password.data(using: String.Encoding.utf8)!, forKey: kSecValueData as String)
    
            return instance.save(dictionry: dictionry);
        }
        
        public class func getUserAccount(server:String) -> String{
            
            var dict:Dictionary = Dictionary<String, Any>()
            dict.updateValue(server, forKey: kSecAttrServer as String)
            
            let dictionry = instance.readData(dict: dict) as Dictionary;
            
            guard let account = dictionry[kSecAttrAccount as String] as? String else {
               return  "";
            }
            return account
        }
        
        public class func getUserPassword(server:String) -> String{
            
            var dict:Dictionary = Dictionary<String, Any>()
            dict.updateValue(server, forKey: kSecAttrServer as String)
            
            let dictionry = instance.readData(dict: dict);
            
            guard let passwordData = dictionry[kSecValueData as String] as? Data,
                let password = String(data: passwordData, encoding: String.Encoding.utf8) else {
               return  "";
            }
            return password
        }
        
        public class func getUserPassword(server:String,account:String) -> String{
            
            var dict:Dictionary = Dictionary<String, Any>()
            dict.updateValue(server, forKey: kSecAttrServer as String)
            dict.updateValue(account, forKey: kSecAttrAccount as String)
            
            let dictionry = instance.readData(dict: dict);
            
            guard let passwordData = dictionry[kSecValueData as String] as? Data,
                let password = String(data: passwordData, encoding: String.Encoding.utf8) else {
               return  "";
            }
            return password
        }
        
        public class func deleteUser(server:String){
            
            var dict:Dictionary = Dictionary<String, Any>()
            dict.updateValue(server, forKey: kSecAttrServer as String)
            
            instance.deleteData(dict: dict);
        }
        
        public class func deleteUser(server:String,account:String){
            
            var dict:Dictionary = Dictionary<String, Any>()
            dict.updateValue(server, forKey: kSecAttrServer as String)
            dict.updateValue(account, forKey: kSecAttrAccount as String)
            
            instance.deleteData(dict: dict);
        }
        
        public func save(dictionry:Dictionary<String, Any>) -> Bool {
            if dictionry[kSecAttrAccount as String] == nil || dictionry[kSecAttrServer as String] == nil || dictionry[kSecValueData as String] == nil{
                return false;
            }
            
            // 进行存储数据
            let saveStatus = SecItemAdd(dictionry as CFDictionary, nil)
            
            if saveStatus == noErr  {
                return true
            }else{
                print("Error save cer to keychain. Error: \(saveStatus)")
                return false
            }
            
        }
        
        /*
         更新数据
         */
        private func updateData(dict:Dictionary<String, Any>)->Bool {
            // 获取更新的条件
            var attributes = dict
            attributes.removeValue(forKey: kSecAttrServer as String);
            // 创建数据存储字典
            var query = Dictionary<String, Any>()
            // 设置数据
            query.updateValue(kSecClassInternetPassword, forKey: kSecClass as String)
            query.updateValue(dict[kSecAttrServer as String] ?? "", forKey: kSecAttrServer as String)
            
            // 更新数据
            let updateStatus = SecItemUpdate(query as CFDictionary, attributes as CFDictionary)
            if updateStatus == noErr {
                return true
            }else{
                print("Error update cer to keychain. Error: \(updateStatus)")
                return false
            }
            
        }
        
        
        /*
         获取数据
         */
        private func readData(dict:Dictionary<String, Any>)-> Dictionary<String,Any> {
            
            // 获取查询条件
            var keyChainReadmutableDictionary = dict;
            // 提供查询数据的两个必要参数
            keyChainReadmutableDictionary.updateValue(true , forKey: kSecReturnData as String)
            keyChainReadmutableDictionary.updateValue(kSecMatchLimitOne, forKey: kSecMatchLimit as String)
            keyChainReadmutableDictionary.updateValue(true, forKey: kSecReturnAttributes as String)
            keyChainReadmutableDictionary.updateValue(kSecClassInternetPassword, forKey: kSecClass as String)
            // 创建获取数据的引用
            var item: CFTypeRef?
            // 通过查询是否存储在数据
            let readStatus =  SecItemCopyMatching(keyChainReadmutableDictionary as CFDictionary, &item)
            if readStatus == errSecSuccess {
                guard let existItem = item as? [String : Any]
                else {
                    print("Error search cer to keychain. Error: \(readStatus)")
                    return Dictionary.init()
                }
                
    //            let passwordData = existingItem[kSecValueData as String] as? Data,
    //            let password = String(data: passwordData, encoding: String.Encoding.utf8),
    //            let account = existingItem[kSecAttrAccount as String] as? String
                return existItem;
                
            }
            
            return Dictionary.init()
        }
        
        /*
         删除数据
         */
        private func deleteData(dict:Dictionary<String, Any>)->Void{
            // 获取删除的条件
           // 创建数据存储字典
            var query = Dictionary<String, Any>()
            // 设置数据
            query.updateValue(kSecClassInternetPassword, forKey: kSecClass as String)
            query.updateValue(dict[kSecAttrServer as String] ?? "", forKey: kSecAttrServer as String)
            // 删除数据
           let deleteStatus = SecItemDelete(query as CFDictionary)
             
            if deleteStatus != noErr {
                print("Error delete cer to keychain. Error: \(deleteStatus)")
            }
        }
    }
    

    工具类二

    //
    //  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)
        }
    }
    

    工具类三

    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 Swift用keychain保存用户名和密码

          本文链接:https://www.haomeiwen.com/subject/vbwtertx.html