React Native Keychain数据无法持久化问题求助
问题:react-native-keychain存储数据重启应用后丢失
我在开发模式下使用react-native-keychain存储用户名和密码,同时在模拟器和iOS设备(通过Xcode构建)上运行应用。存储完成后不重启应用能正常获取到数据,但一旦从终端重启应用,所有数据都会被清除,获取操作始终返回false。
存储数据的Redux Action代码
export function fetchLoginDetails(loginData) { console.log(loginData) return async function fetchLoginDetailsThunk(dispatch, getState) { dispatch(setLoading(true)) try { const { data } = await axios.post(`url/login`, loginData); if (data.statuscode === 200) { await Keychain.setGenericPassword(loginData.email, loginData.password, { service: 'org.AppNameKeyStore', keychainAccessGroup: 'AppNameKeyStore.com.AppName' }) await dispatch(setEmail(loginData.email)); await dispatch(setUserId(data.data.id)); Toast.show({ text1: `Otp has been sent to registered email`, type: 'success', position: 'bottom' }) } dispatch(setLoading(false)) } catch (error) { dispatch(setError(error.response.data.message)) Toast.show({ text1: `${error.response.data.message}`, duration: 3000, type: 'error', position: 'bottom' }) dispatch(setLoading(false)) } } }
获取数据的代码
useEffect(() => { getkeyChainValue(); }, []); const getkeyChainValue = async () => { const options = { service: 'org.AppNameKeyStore' }; const password = await Keychain.getGenericPassword(options); console.log(password,'password') } // 应用不重启时的正常返回: // {"password": "password", "service": "org.AppNameKeyStore", "storage": "keychain", "username": "username@email.com"}
问题原因及解决办法
keychainAccessGroup参数不匹配
存储数据时指定了keychainAccessGroup: 'AppNameKeyStore.com.AppName',但获取数据时的options里缺少这个参数。iOS的keychain访问组是严格匹配的,必须在读取时传入相同的accessGroup才能跨会话读取数据。修改获取代码的options:
const options = { service: 'org.AppNameKeyStore', keychainAccessGroup: 'AppNameKeyStore.com.AppName' };开发模式下的应用签名/安装问题
- 检查Xcode中Capabilities的Keychain Sharing是否已开启,且添加了与代码中一致的访问组
AppNameKeyStore.com.AppName。 - 模拟器中通过
react-native run-ios重启应用时,可能会重新安装应用导致keychain被清空,建议直接在Xcode中点击重启按钮,而非通过终端重新执行run命令。
- 检查Xcode中Capabilities的Keychain Sharing是否已开启,且添加了与代码中一致的访问组
添加错误排查逻辑
当前获取代码未处理读取失败的情况,建议添加try/catch捕获错误,明确是读取失败还是数据不存在:const getkeyChainValue = async () => { try { const options = { service: 'org.AppNameKeyStore', keychainAccessGroup: 'AppNameKeyStore.com.AppName' }; const password = await Keychain.getGenericPassword(options); console.log(password,'password') } catch (error) { console.error('读取keychain失败:', error); } }
内容的提问来源于stack exchange,提问作者Kamlesh Prajapati
相关产品推荐
相关产品推荐

