【发布时间】:2017-02-26 17:21:51
【问题描述】:
我需要从 iOS 原生 Objective C 代码访问存储在 AsyncStorage 中的数据。
这是同步数据所必需的,而不是向 JS 发送 App 事件,然后将其发送回本机代码。
【问题讨论】:
-
你有没有想过这个问题?
标签: ios objective-c react-native
我需要从 iOS 原生 Objective C 代码访问存储在 AsyncStorage 中的数据。
这是同步数据所必需的,而不是向 JS 发送 App 事件,然后将其发送回本机代码。
【问题讨论】:
标签: ios objective-c react-native
我认为您可以为此目的使用实现 AsyncStorage 中的代码。你可以看到它here。它基本上使用NSFileManager 加载存储数据的文件,然后相应地解析它们。在您的情况下,例如查看multiGet method,然后跟踪文件中存在的所有必需函数。有了它,您应该能够重新实现(或适应)它们以满足您的需求。
【讨论】:
我也遇到了同样的问题。
我的解决方案是移动代码原生端。
在 iOS 上:
#import <React/RCTAsyncLocalStorage.h>
#import <React/RCTBridgeModule.h>
RCTResponseSenderBlock completion = ^(NSArray *response) {
NSString *theme = response[1][0][0][1];
// Setup RCTRootView with initialProperties
};
RCTAsyncLocalStorage *storage = [[RCTAsyncLocalStorage alloc] init];
dispatch_async(storage.methodQueue, ^{
[storage performSelector:@selector(multiGet:callback:) withObject:@[@"theme"] withObject:completion];
});
您还可以使用 dispatch_semaphore_wait 同步执行此操作
更新:
我需要全局状态中的变量,而不仅仅是在组件道具中,所以上面的内容还不够。
在加载 Javascript 源代码时,我必须将它处理到 React Native 源代码中。
NSString *javascriptPrepend = [NSString stringWithFormat:@"var ThemeMode = '%@';", self.theme];
NSMutableData *prependData = [[javascriptPrepend dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
[prependData appendData:sourceCode];
sourceCode = prependData;
我会看看他们是否对 PR 开放以允许这种功能,如果我通过了,我会在此处回复。
【讨论】:
增强@luke 的解决方案——修复response 中数据位置的问题;将 JSON 数据转换为 NSDictionary 并确保代码的安全性——这是完整的方法:
+(void)jsonFromLocalRNStrogeForKey:(NSString *)key completion:(void (^)(NSDictionary * _Nullable, NSError * _Nullable))completion
{
RCTResponseSenderBlock rnCompletion = ^(NSArray *response) {
NSString *jsonAsString;
if (response.count > 1) {
NSArray *response1 = response[1];
if (response1.count > 0) {
NSArray *response2 = response1[0];
if (response2.count > 1) {
jsonAsString = response2[1];
}
}
}
NSData *jsonAsData = [jsonAsString dataUsingEncoding:NSUTF8StringEncoding];
NSError *error;
NSDictionary *json = [NSJSONSerialization
JSONObjectWithData:jsonAsData options:NSJSONReadingMutableContainers error:&error];
completion(json, error);
};
RCTAsyncLocalStorage *storage = [RCTAsyncLocalStorage new];
dispatch_async(storage.methodQueue, ^{
[storage performSelector:@selector(multiGet:callback:) withObject:@[key] withObject:rnCompletion];
});
}
【讨论】:
catalystLocalStorage 开始,其中整个 data 仅作为 json 字符串 在第一行,而在 iOS 上我尝试了 user 和group.MyApp 但jsonAsString 它始终为空。你知道 iOS 的主要关键是什么吗?
我目前的解决方案。从技术上讲,这不是问题的直接答案,但确实提供了在 Javascript 和本机代码之间共享数据的解决方法,即使用 NSUserDefaults。
使用这个包,react-native-default-preferences 可以轻松地将数据保存到 NSUserdefaults 中,然后在本机端轻松地正常检索它们。
出于我的目的,我将保存在 Javascript 中检索到的令牌,以供以后应用程序的扩展使用。这意味着我还坚持使用与我的应用相同的密钥的 UserDefaults 套件。
React Native(Javascript):
DefaultPreference.setName('group.myApp');
DefaultPreference.set('TOKEN', token);
目标-C:
NSString *TOKEN = [[[NSUserDefaults alloc] initWithSuiteName:@"group.myApp"] stringForKey:@"TOKEN"];
【讨论】:
group.myApp 是 iOS 使用的默认名称吗?如果应用名称是 TheApp,我应该致电 group.TheApp 吗?
group.YOUR_APPS_NAME 的名称来访问相同的共享 NSUserDefaults。