Save and retrieve value via KeyChain

后端 未结 7 1747
自闭症患者
自闭症患者 2020-12-02 09:51

I\'m trying to store an Integer and retrieve it using KeyChain.

This is how I save it:

func SaveNumberOfImagesTaken()
    {
        let key = \"IMAGE         


        
7条回答
  •  -上瘾入骨i
    2020-12-02 10:06

    This is Sazzad Hissain Khan's answer rewritten for iOS without non-Swifty NS-prefixed attributes and a cleaner code.

    import Security
    
    class KeychainService {
        class func updatePassword(service: String, account: String, data: String) {
            guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
                return
            }
    
            let status = SecItemUpdate(modifierQuery(service: service, account: account), [kSecValueData: dataFromString] as CFDictionary)
    
            checkError(status)
        }
    
        class func removePassword(service: String, account: String) {
            let status = SecItemDelete(modifierQuery(service: service, account: account))
    
            checkError(status)
        }
    
        class func savePassword(service: String, account: String, data: String) {
            guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else {
                return
            }
    
            let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
                                                  kSecAttrService: service,
                                                  kSecAttrAccount: account,
                                                  kSecValueData: dataFromString]
    
            let status = SecItemAdd(keychainQuery as CFDictionary, nil)
    
            checkError(status)
        }
    
        class func loadPassword(service: String, account: String) -> String? {
            var dataTypeRef: CFTypeRef?
    
            let status = SecItemCopyMatching(modifierQuery(service: service, account: account), &dataTypeRef)
    
            if status == errSecSuccess,
                let retrievedData = dataTypeRef as? Data {
                return String(data: retrievedData, encoding: .utf8)
            } else {
                checkError(status)
    
                return nil
            }
        }
    
        fileprivate static func modifierQuery(service: String, account: String) -> CFDictionary {
            let keychainQuery: [CFString: Any] = [kSecClass: kSecClassGenericPassword,
                                                  kSecAttrService: service,
                                                  kSecAttrAccount: account,
                                                  kSecReturnData: kCFBooleanTrue]
    
            return keychainQuery as CFDictionary
        }
    
        fileprivate static func checkError(_ status: OSStatus) {
            if status != errSecSuccess {
                if #available(iOS 11.3, *),
                let err = SecCopyErrorMessageString(status, nil) {
                    print("Operation failed: \(err)")
                } else {
                    print("Operation failed: \(status). Check the error message through https://osstatus.com.")
                }
            }
        }
    }
    

提交回复
热议问题