I have the following function:
func saveCredential(_ credential: String, service: String, account: String) async throws {
let query = [
kSecValueData: credential.data(using: .utf8)!,
kSecClass: kSecClassGenericPassword,
kSecUseDataProtectionKeychain: true,
kSecAttrSynchronizable: true,
kSecAttrService: service,
kSecAttrAccount: account,
] as CFDictionary
let status = (Task {
// Add data in query to keychain
return SecItemAdd(query, nil)
}).value
switch status {
case errSecSuccess:
return;
case errSecDuplicateItem:
try updateCredential(credential, service: service, account: account)
default:
try throwStatus(status)
}
}
While discussing whether this is the idiomatic way to do this code, someone in a discord server said that it would be cleaner to write this as:
func addKeychainItem(attributes attrs: CFDictionary) async -> (OSStatus, CFTypeRef?) {
return await withUnsafeContinuation { continuation in
var item: CFTypeRef?
let result = SecItemAdd(attrs, &item)
completion(result, item)
}
}
Now, this code obviously doesn't do the same thing as the example above, because it has a bunch of stuff left out, but is there a functional difference between the two? An is one of them indeed considered more idiomatic?