RN—使用Keychain存储

1、安装Keychain

npm install react-native-keychain

2、定义成工具类

import * as Keychain from 'react-native-keychain';

export class LMKeyChain {

    /**
     * 存储
     * @param key 
     * @param value 
     */
    async set(key: string,value :string): Promise<boolean>{
        const result =  await Keychain.setGenericPassword(key,value,{
            service: key
        })

        if(result === false){
            return false;
        }else{
            return true;
        }
    }

    /**
     * 获取
     * @param key 
     * @returns 
     */
    async get(key: string): Promise<string | null> {
        const credentials = await Keychain.getGenericPassword({
            service: key
        });
        
        if(credentials){
            return credentials.password;
        }
        return null;
    }

    /**
     * 判断是否存在该key
     * @param key 
     * @returns 
     */
    async exist(key: string): Promise<boolean> {
        return Keychain.hasGenericPassword({
            service: key
        });
    }

    /**
     * 删除
     * @param key 
     */
    async remove(key: string) : Promise<boolean>{
        return Keychain.resetGenericPassword({
            service: key
        })
    }
}

3、单元测试

import { LMKeyChain } from "../rn/utils/LMKeyChain";

jest.mock('react-native-keychain', () => ({
  setGenericPassword: jest.fn().mockResolvedValue(true),
  getGenericPassword: jest.fn().mockResolvedValue({
    username: 'tdjgamtam',
    password: '乔乔'
  }),
}));

describe('',() => {
    test('测试', async () => { 
        const keyChain = new LMKeyChain();
        const key = "tdjgamtam";
        const value = "乔乔";
        
        await keyChain.set(key,value);

        const destValue = await keyChain.get(key);

        expect(value).toBe(destValue);
     })
});

会报错:

报错原因:

错误信息说 Cannot read properties of undefined,这意味着在 react-native-keychain 内部,它尝试访问一个 undefined 对象的 setGenericPasswordForOptions 属性。

其具体原因是 react-native-keychain 依赖原生模块(Native Module),而 Jest 运行在 Node 环境里,没有 React Native 的原生实现。因些需要使用mock进行模拟。

import { LMKeyChain } from "../rn/utils/LMKeyChain";

jest.mock('react-native-keychain', () => ({
  setGenericPassword: jest.fn().mockResolvedValue(true),
  getGenericPassword: jest.fn().mockResolvedValue({
    username: 'tdjgamtam',
    password: '乔乔'
  }),
}));

describe('',() => {
    test('测试', async () => { 
        const keyChain = new LMKeyChain();
        const key = "tdjgamtam";
        const value = "乔乔";
        
        await keyChain.set(key,value);

        const destValue = await keyChain.get(key);

        expect(value).toBe(destValue);
     })
});

注意,模拟中使用的username与password关键字不是随意选的,因为kyechain中定义了这两个key。