As usual, we first need a CFDictionary
to represent the item we want to update. This must contain all of the old values for the item, including the old private data. Then it takes a CFDictionary
of any attributes or the data itself that you would like to change.
So first, let's construct a class key and a list of attributes. These attributes can narrow our search but you must include any attributes and there old values if you will be changing them.
var dict = [String : AnyObject]()
dict[kSecClass as String] = kSecClassGenericPassword
// Label
dict[kSecAttrLabel as String] = "com.me.myapp.myaccountpassword" as CFString
// Username
dict[kSecAttrAccount as String] = "My Name" as CFString
Now we must add the old data:
dict[kSecValueData as String] = "my_password!!".data(using: .utf8) as! CFData
Now let's create the same attributes but a different password:
var newDict = [String : AnyObject]()
newDict[kSecClass as String] = kSecClassGenericPassword
// Label
newDict[kSecAttrLabel as String] = "com.me.myapp.myaccountpassword" as CFString
// Username
newDict[kSecAttrAccount as String] = "My Name" as CFString
// New password
newDict[kSecValueData as String] = "new_password!!".data(using: .utf8) as! CFData
Now, we just pass it to Keychain Services:
let status = SecItemUpdate(dict as CFDictionary, newDict as CFDictionary)
SecItemUpdate
returns a status code. Results are described here.