Swift 4 Keychain中SecItemUpdate报错status code -50求助
解决Keychain更新操作返回错误码-50的问题
你遇到的错误码-50(对应errSecParam)确实是参数无效导致的,我帮你拆解下问题根源和修复方案:
问题核心原因
调用SecItemUpdate时,第一个参数(查询字典)只能包含用于匹配已有Keychain项的条件,不能混入kSecReturnData、kSecMatchLimit这类控制返回结果的参数——这些是查询操作(SecItemCopyMatching)专属的配置,放在更新的查询字典里会被系统判定为无效参数。
另外,你把Core Foundation原生常量转成NSString的操作完全没必要,直接使用原常量不仅更安全,还能避免潜在的类型匹配问题。
修正后的完整代码
public class KeychainService: NSObject { class func updatePassword(service: String, account: String, data: String) { guard let dataFromString = data.data(using: .utf8, allowLossyConversion: false) else { print("Failed to convert input string to Data") return } // 仅保留用于定位目标项的匹配条件 let query: [CFString: Any] = [ kSecClass: kSecClassGenericPassword, kSecAttrService: service, kSecAttrAccount: account ] // 构建要更新的属性字典 let updateAttributes: [CFString: Any] = [ kSecValueData: dataFromString ] // 执行更新操作 let status = SecItemUpdate(query as CFDictionary, updateAttributes as CFDictionary) if status != errSecSuccess { if let errMsg = SecCopyErrorMessageString(status, nil) { print("Update failed: \(errMsg)") print("Status code: \(status)") } } else { print("Password updated successfully") } } // ...其他Keychain操作方法 }
关键修改说明
- 移除了查询字典中的
kSecReturnData和kSecMatchLimit,只保留kSecClass、kSecAttrService、kSecAttrAccount三个核心匹配条件,确保系统能准确定位到要更新的项。 - 直接使用Core Foundation原生常量,避免不必要的类型转换。
- 用
guard语句更优雅地处理字符串转Data的失败场景,提前退出并给出提示。
额外提示
如果后续遇到errSecItemNotFound(状态码-25300),说明没有找到匹配的Keychain项,这时候你可能需要先执行插入操作,或者在更新前先检查目标项是否存在。
内容的提问来源于stack exchange,提问作者slugz
相关产品推荐
相关产品推荐

