You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:46:20