I want to support multiple accounts in my iOS app and I'm using the KeyChain to store credentials. I'm storing accounts with the same class (kSecClassGenericPassword) and attribute (kSecAttrService) but with a different username (kSecAttrAccount). This works fine and I can log in with the different usernames.
I now want to retrieve these usernames and this is where I'm running into problems. I define and execute my query as:
let objects = [kSecClassGenericPassword, "foo", kCFBooleanTrue,kSecMatchLimitAll]
let keys = [kSecClass,kSecAttrService kSecReturnAttributes,kSecMatchLimit]
let query = NSDictionary(objects: objects, forKeys: keys)
var dataTypeRef : Unmanaged<AnyObject>?
let status = SecItemCopyMatching(query, &dataTypeRef)
But only one item is returned. My dataTypeRef is a CFDictionary whereas I expected it to be a CFArray.
According to the Apple Docs on SecItemCopyMatching
By default, this function returns only the first match found. To obtain more than one matching item at a time, specify the search key kSecMatchLimit with a value greater than 1. The result will be an object of type CFArrayRef containing up to that number of matching items.
As you can see from my code I've done this but with no luck.
Can anyone point me in the right direction ?
Accordingly to Apple Doc on SecItemCopyMatching the second parameter of this function is a UnsafeMutablePointer<AnyObject?>.
Notice that this is information from the most recent documentation.
let keychainQuery: [NSObject: AnyObject] = [
kSecClass : kSecClassInternetPassword,
kSecReturnAttributes : kCFBooleanTrue,
kSecMatchLimit : kSecMatchLimitAll
]
var result: AnyObject?
let status = withUnsafeMutablePointer(&result) {
SecItemCopyMatching(keychainQuery, UnsafeMutablePointer($0))
}
if status == noErr {
print(result)
}
I'm currently using this is in a project and it works great.
Hope that can helps you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With