I am, at least, per success of the operation able to store a username and password in the keychain using the "addUser" function in the code below. I then when doing a login call the "authenticateUser" function but I get a -25300 error (errSecItemNotFound). I'm close here but missing something. Any help would be appreciated.
class func addUser(username: String, password: String) -> Bool {
let serviceName = AppValues.appName // Replace this with a unique identifier for your app
let account = username.data(using: .utf8)!
let passwordData = password.data(using: .utf8)!
let query: [CFString: Any] = [
kSecClass: kSecClassGenericPassword,
kSecAttrService: serviceName,
kSecAttrAccount: account,
kSecValueData: passwordData,
kSecAttrAccessible: kSecAttrAccessibleWhenUnlockedThisDeviceOnly
]
// Delete any existing items with the same account before adding the new one
SecItemDelete(query as CFDictionary)
let status = SecItemAdd(query as CFDictionary, nil)
guard status == errSecSuccess else {
evaluateKeychainError(errorCode: status)
return false
}
LogEvent.print(module: "Authentication.keychain.addUser", message: "\(username)/\(password) added successfully.")
return true
}
class func authenticateUser(username: String, password: String) -> Bool {
let usernameData = username.data(using: .utf8)!
let query: [String: Any] = [
kSecClass as String: kSecClassInternetPassword,
kSecAttrServer as String: AppValues.appName, // Replace with your server or app identifier
kSecAttrAccount as String: usernameData,
kSecReturnData as String: true,
kSecMatchLimit as String: kSecMatchLimitOne
]
var result: AnyObject?
let status = SecItemCopyMatching(query as CFDictionary, &result)
if status == errSecSuccess,
let passwordData = result as? Data,
let retrievedPassword = String(data: passwordData, encoding: .utf8) {
LogEvent.print(module: "Authentication.keychain.authenticateUser", message: "\(username)/\(password)/\(retrievedPassword) authenticated successfully.")
return retrievedPassword == password
} else {
LogEvent.print(module: "Authentication.keychain.authenticateUser", message: "Error \(status)")
evaluateKeychainError(errorCode: status)
return false
}
}