Finding a Password in the Keychain
suggest changeTo 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.
Found a mistake? Have a question or improvement idea?
Let me know.
Table Of Contents