iOS Finding a Password in the Keychain


Example

To construct a query, we need to represent it as a CFDictionary. You may also use NSDictionary in Objective-C or Dictionary in Swift and cast to CFDictionary.

We need a class key:

Swift

var dict = [String : AnyObject]()
dict[kSecClass as String] = kSecClassGenericPassword

Next, we can specify attributes to narrow down our search:

Swift

// Label
dict[kSecAttrLabel as String] = "com.me.myapp.myaccountpassword" as CFString
// Username
dict[kSecAttrAccount as String] = "My Name" as CFString
// Service name
dict[kSecAttrService as String] = "MyService" as CFString

We can also specify special search modifier keys described here.

Finally, we need to say how we'd like our data returned. Below, we'll request that just the private password itself be returned as a CFData object:

Swift

dict[kSecReturnData as String] = kCFBooleanTrue

Now, let's search:

Swift

var queryResult: AnyObject?
let status = withUnsafeMutablePointer(to: &queryResult) {
    SecItemCopyMatching(dict as CFDictionary, UnsafeMutablePointer($0))
}
// Don't keep this in memory for long!!
let password = String(data: queryResult as! Data, encoding: .utf8)!

Here, SecItemCopyMatching takes in a query dictionary and a pointer to where you'd like the result to go. It returns an OSStatus with a result codes. Here are the possibilities.