Save and retrieve value via KeyChain

后端 未结 7 1791
自闭症患者
自闭症患者 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条回答
  •  臣服心动
    2020-12-02 09:57

    I've update Eric's version for Swift 5:

    class KeyChain {
    
        class func save(key: String, data: Data) -> OSStatus {
            let query = [
                kSecClass as String       : kSecClassGenericPassword as String,
                kSecAttrAccount as String : key,
                kSecValueData as String   : data ] as [String : Any]
    
            SecItemDelete(query as CFDictionary)
    
            return SecItemAdd(query as CFDictionary, nil)
        }
    
        class func load(key: String) -> Data? {
            let query = [
                kSecClass as String       : kSecClassGenericPassword,
                kSecAttrAccount as String : key,
                kSecReturnData as String  : kCFBooleanTrue!,
                kSecMatchLimit as String  : kSecMatchLimitOne ] as [String : Any]
    
            var dataTypeRef: AnyObject? = nil
    
            let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
    
            if status == noErr {
                return dataTypeRef as! Data?
            } else {
                return nil
            }
        }
    
        class func createUniqueID() -> String {
            let uuid: CFUUID = CFUUIDCreate(nil)
            let cfStr: CFString = CFUUIDCreateString(nil, uuid)
    
            let swiftString: String = cfStr as String
            return swiftString
        }
    }
    
    extension Data {
    
        init(from value: T) {
            var value = value
            self.init(buffer: UnsafeBufferPointer(start: &value, count: 1))
        }
    
        func to(type: T.Type) -> T {
            return self.withUnsafeBytes { $0.load(as: T.self) }
        }
    }
    

    I've update Eric's version for Swift 3:

    class KeyChain {
    
        class func save(key: String, data: Data) -> OSStatus {
            let query = [
                kSecClass as String       : kSecClassGenericPassword as String,
                kSecAttrAccount as String : key,
                kSecValueData as String   : data ] as [String : Any]
    
            SecItemDelete(query as CFDictionary)
    
            return SecItemAdd(query as CFDictionary, nil)
        }
    
        class func load(key: String) -> Data? {
            let query = [
                kSecClass as String       : kSecClassGenericPassword,
                kSecAttrAccount as String : key,
                kSecReturnData as String  : kCFBooleanTrue,
                kSecMatchLimit as String  : kSecMatchLimitOne ] as [String : Any]
    
            var dataTypeRef: AnyObject? = nil
    
            let status: OSStatus = SecItemCopyMatching(query as CFDictionary, &dataTypeRef)
    
            if status == noErr {
                return dataTypeRef as! Data?
            } else {
                return nil
            }
        }
    
        class func createUniqueID() -> String {
            let uuid: CFUUID = CFUUIDCreate(nil)
            let cfStr: CFString = CFUUIDCreateString(nil, uuid)
    
            let swiftString: String = cfStr as String
            return swiftString
        }
    }
    
    extension Data {
    
        init(from value: T) {
            var value = value
            self.init(buffer: UnsafeBufferPointer(start: &value, count: 1))
        }
    
        func to(type: T.Type) -> T {
            return self.withUnsafeBytes { $0.pointee }
        }
    }
    

    Example usage:

    let int: Int = 555
    let data = Data(from: int)
    let status = KeyChain.save(key: "MyNumber", data: data)
    print("status: ", status)
    
    if let receivedData = KeyChain.load(key: "MyNumber") {
        let result = receivedData.to(type: Int.self)
        print("result: ", result)
    }
    

提交回复
热议问题