keychain 踩坑指南

冷启动时有概率取不到 keychain

网上很不少关于这个问题的讨论,而且需要像 facebook 这样的大厂也有中招 对于这个问题官方给了一些说法:The best we can tell so far, it’s an issue with accessing the keychain too soon after the app has been launched or resumed. 个人猜测因为 app 启动时总会伴随着内存增长,keychain 的这个问题是因为内存压力导致的,毕竟 keychain 的获取涉及到加解密逻辑,苹果方面建议开发者在 application:didFinishLaunchingWithOptions 或者 application:didBecomeActive 之后再获取 keychain 来缓解这个问题: -w250

网上一些相关的讨论:Error -34018 (errSecDefault) · Issue #52 · soffes/SAMKeychain · GitHub

Returns nil when just appeared from background · Issue #20 · kishikawakatsumi/UICKeyChainStore · GitHub

[Keychain error -34018 (errSecMissingEntitlement) Apple Developer Forums](https://forums.developer.apple.com/thread/4743?start=30&tstart=0)

还有一个专门复现此问题的 sample: GitHub - DinosaurDad/Keychain-34018: This project is only intended to help track down error -34018 with the iOS keychain.

app 切到后台后有概率取不到 keychain

App 进入后台一段时间,这时候触发一个取 keychain 的操作有一定概率可以复现此问题 解决办法有三个: ① 应用在后台时不去取 keychain,keychain 中的内容通常是机密性比较强的,在后台取这些数据在逻辑上应该尽量避免 ② 在 app 启动以后的适当时机,取出 keychain 内容并存储在内存中,下次去内存中的值即可 ③ 设置 AccessibilityType 为 kSecAttrAccessibleAfterFirstUnlock,网上有人反映说设置了以后还是偶尔会有取不到的情况,个人推测可能可以解决部分问题。

一些讨论:Keychain retain a nil after long time in background · Issue #15 · evgenyneu/keychain-swift · GitHub

Keychain data seems to be disappearing · Issue #75 · soffes/SAMKeychain · GitHub

iphone - iOS KeyChain not retrieving values from background - Stack Overflow

app id 变化后,keychain 数据会丢失

App ID Prefix 是用来标识一组 app 的,这些 app 可以进行 keychain 共享数据和剪贴板共享数据。 如果某个 App 已经维护很久的时间了,那么有可能会存在新旧 App ID 的问题,新版本的 App ID Prefix 就是 team ID,老版本的 App ID Prefix 则是一个长度为 10 的由数字和字母组成的串。 2011 年 6 月以后创建的新 App 已经统一使用新的 App ID 使用旧 App ID 的 App 并不一定都需要切换成新 ID,因为旧 App ID 对应的 keychain 存储空间依旧存在,且可以继续使用,但是如果想要和新创建的 app 或者 extension 共享 keychain 或者粘贴板信息,那么就需要进行一次 App ID prefix 的切换。 在实际项目中我们就遇到了这样的问题,App 是在 2011 年之前就创建了的,2011 年之后,我们又上线了 extension,我们发现 extension 内获取到的 App ID 与主程序中获取到的不一致,这时候我们就有必要进行一次 App ID prefix 的切换工作。 但是切换 prefix 的过程前后,苹果并不会帮我们将旧的 keychain 信息迁移到新的 keychain 空间中,这就会导致切换后所有的 keychain 信息会丢失一次。

参考: https://developer.apple.com/library/archive/technotes/tn2311/_index.html https://developer.apple.com/library/archive/qa/qa1879/_index.html

app 或者 extension 想共享 keychain 需要设置 access group

详细可以参考之前的文章:https://linkexin.github.io/notes/%E7%B3%BB%E7%BB%9F%E5%88%86%E4%BA%AB-Share-Extension 常用第三方库 SAMKeychain 并不提供设置 access group 的接口,并且以后也不准备支持,参考:Added support for access group by AsceticMonk · Pull Request #81 · soffes/SAMKeychain · GitHub