钥匙串 SecItemUpdate 返回 errSecParam

Keychain SecItemUpdate returning errSecParam

我可以将项目添加到钥匙串,我什至可以读出它们。

但是,我很难使用 SecItemUpdate 来更新一个值,而且似乎每次都返回 errSecParam。

为此,我创建了以下查询和属性(这里很可能是个问题)

let query: [String: Any] = [kSecAttrAccount as String : "MyString",
    kSecValueData as String: "test2".data(using: .utf16)!,
    kSecMatchLimit as String  : kSecMatchLimitOne
]

let attributes: [String: Any] = [kSecAttrAccount as String: "aa",
                                         kSecValueData as String: data]

然后用于更新

SecItemUpdate(query as CFDictionary, attributes as CFDictionary)

应该在查询中指定 class 而不是数据(用于更新),因此,例如,钥匙串中的 add/update 密码应该如下所示

// adding item
let addQuery: [CFString: Any] = [
    kSecClass: kSecClassGenericPassword,
    kSecAttrService: service as CFString,        // eg. "www.mysite.com"
    kSecAttrAccount: name as CFString            // eg. "user"
    kSecValueData: password.data(using: .utf8)   // eg. "password"
] as CFDictionary

if errSecSuccess != SecItemAdd(addQuery, nil) { 
    // report error here
}

// updating item (same query is for SecItemDelete)

let updateQuery: [CFString: Any] = [
    kSecClass: kSecClassGenericPassword,
    kSecAttrService: service as CFString,        // eg. "www.mysite.com"
    kSecAttrAccount: name as CFString            // eg. "user"
] as CFDictionary

let newAttributes = [
    kSecAttrAccount: newName as CFString            // eg. "user1"
    kSecValueData: newPassword.data(using: .utf8)   // eg. "password1"
] as CFDictionary

if errSecSuccess != SecItemUpdate(updateQuery, newAttributes) {
   // report error here
}