React Native 0.48.4 iOS原生获取AsyncStorage遇问题求助
解决React Native 0.48.4 iOS原生获取AsyncStorage数据的问题
嘿,我来帮你搞定这个iOS原生调用RN AsyncStorage的棘手问题!咱们先拆解你遇到的两个核心问题,再一步步给出解决方案:
1. 为啥getAllKeys会触发异常?
你看到RCTAsyncLocalStorage.m里有getAllKeys方法,但头文件没声明——这是因为RCT_EXPORT_METHOD宏只负责把方法暴露给JS引擎,不会自动更新头文件。iOS原生调用未在头文件声明的方法时,运行时会找不到方法选择器,哪怕你手动加了头文件,也可能因为编译缓存没清而不生效。不过咱们有更稳妥的绕开方式。
2. 正确获取并解析AsyncStorage数据的两种方法
方法一:用运行时调用绕过头文件限制
既然RCTAsyncLocalStorage实例确实存在这些方法,咱们可以用Objective-C的运行时特性直接调用,不用纠结头文件:
// 先导入头文件 #import <React/RCTAsyncLocalStorage.h> // 获取AsyncStorage单例 RCTAsyncLocalStorage *storage = [RCTAsyncLocalStorage sharedInstance]; // 调用getAllKeys,用performSelector绕过头文件检查 [storage performSelector:@selector(getAllKeys:) withObject:^(NSArray *keys) { // 拿到所有key后,调用multiGet批量获取数据 [storage performSelector:@selector(multiGet:callback:) withObject:keys withObject:^(NSArray *results) { // 把返回的数组解析成字典 NSMutableDictionary *parsedStorage = [NSMutableDictionary dictionary]; for (NSArray *keyValuePair in results) { NSString *key = keyValuePair[0]; NSString *jsonString = keyValuePair[1]; if (jsonString) { NSError *parseError; id value = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&parseError]; if (!parseError) { parsedStorage[key] = value; } } } // 这里的parsedStorage就是你要的解析后的字典啦 NSLog(@"解析完成的AsyncStorage数据:%@", parsedStorage); }]; }];
这种方法完全贴合RN的AsyncStorage逻辑,能拿到和JS层一致的数据。
方法二:直接读取底层存储文件
在RN 0.48.4里,iOS的AsyncStorage数据存在Library/Preferences目录下的plist文件里,文件名和你的App Bundle ID对应(比如com.yourcompany.yourappAsyncLocalStorage.plist)。你可以直接读取这个文件:
// 获取Preferences目录路径 NSString *preferencesDir = [NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES) firstObject]; preferencesDir = [preferencesDir stringByAppendingPathComponent:@"Preferences"]; // 替换成你的App对应的plist文件名 NSString *storageFilePath = [preferencesDir stringByAppendingPathComponent:@"com.yourcompany.yourappAsyncLocalStorage.plist"]; // 读取并解析文件 NSDictionary *rawData = [NSDictionary dictionaryWithContentsOfFile:storageFilePath]; if (rawData) { NSMutableDictionary *parsedDict = [NSMutableDictionary dictionary]; for (NSString *key in rawData.allKeys) { NSString *jsonString = rawData[key]; NSError *error; id value = [NSJSONSerialization JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error]; if (!error) { parsedDict[key] = value; } } NSLog(@"直接读取解析的数据:%@", parsedDict); } else { NSLog(@"AsyncStorage文件不存在或为空"); }
这种方法不用依赖RN模块,适合不需要和RN交互的场景。
3. 为啥之前multiGet返回null?
你之前调用multiGet返回null,大概率是这几个原因:
- 传入的key数组不正确(RN 0.48.4里的key没有前缀,就是你JS里用的原key)
- 没有用异步回调获取结果(
multiGet是异步方法,同步调用肯定拿不到数据) - 对应的key本身就没有存储数据
用方法一的回调链式调用,就能完美避开这些坑啦。
内容的提问来源于stack exchange,提问作者Pablo
相关产品推荐
相关产品推荐

