How to add, match, delete of KeyChain items.

class KeyChain {

    static func add(key: String, data: Data) -> Bool {
        let query = [kSecClass : kSecClassGenericPassword,
                     kSecAttrAccount : key,
                     kSecValueData : data] as [CFString : Any]

        SecItemDelete(query as CFDictionary)
        return SecItemAdd(query as CFDictionary, nil) == noErr
    }

    static func match(key: String) -> Data? {
        let query = [kSecClass : kSecClassGenericPassword,
                     kSecAttrAccount : key,
                     kSecReturnData : kCFBooleanTrue,
                     kSecMatchLimit : kSecMatchLimitOne] as [CFString : Any]

        var dataTypeRef: CFTypeRef?
        let status = withUnsafeMutablePointer(to: &dataTypeRef) {
            SecItemCopyMatching(query as CFDictionary, $0)
        }

        if let data = dataTypeRef as? Data, status == errSecSuccess {
            return data
        }
        return nil
    }

    static func delete(key: String) -> Bool {
        let query = [kSecClass : kSecClassGenericPassword,
                     kSecAttrAccount : key] as [CFString : Any]
        return SecItemDelete(query as CFDictionary) == noErr
    }

    static func clear() -> Bool {
        let query = [kSecClass : kSecClassGenericPassword] as [CFString : Any]
        return SecItemDelete(query as CFDictionary) == noErr
    }

}