Swift Keychain修改kSecAttrAccessible后SecItemCopyMatching返回errSecItemNotFound问题
iOS 钥匙串kSecAttrAccessible属性迁移问题解答
该行为属于预期行为
当你调用SecItemCopyMatching执行钥匙串查询时,如果你在查询参数字典中显式加入了kSecAttrAccessible作为匹配条件,系统会执行严格的等值匹配:
- 旧版本App用
kSecAttrAccessibleAlwaysThisDeviceOnly写入的条目,该属性的存储值就是旧枚举值,自然无法匹配你查询时传入的新枚举值kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly,返回errSecItemNotFound完全符合系统设计。 - 你观察到的反向可读情况,大概率是测试时查询逻辑没有严格指定旧枚举作为匹配条件导致的,如果查询时明确指定了属性值,只要和条目存储的属性不匹配,无论新旧方向都会返回找不到。
无废弃告警的优雅迁移方案
完全不需要引入废弃的旧枚举做中间逻辑,按以下步骤操作即可:
- 移除查询逻辑中的
kSecAttrAccessible条件:定位许可证密钥只需要用核心的唯一匹配条件即可,比如kSecClass、kSecAttrService、kSecAttrAccount这几个固定标识字段,不需要加入 accessibility 属性作为查询条件,就能匹配到所有符合标识的旧条目(无论它的 accessibility 属性是什么值)。 - 查询到旧条目后直接更新属性:拿到查询结果后,调用
SecItemUpdate接口,直接将条目的kSecAttrAccessible属性更新为新的枚举值kSecAttrAccessibleAfterFirstUnlockThisDeviceOnly即可。 - 后续新写入的条目统一使用新的 accessibility 属性即可,整个流程完全不需要引用废弃的旧枚举常量,不会触发任何废弃告警。
注意:更新操作仅需要执行一次即可,你可以在本地做个标记(比如UserDefaults存一个已完成迁移的flag),避免每次启动都重复执行更新逻辑。
内容的提问来源于stack exchange,提问作者cmaltese
相关产品推荐
相关产品推荐

