我需要从iOS本机Objective C代码访问存储在AsyncStorage中的数据。
这需要使数据同步,而不是将App事件发送给JS,然后将其发送回本机代码。
答案 0 :(得分:4)
我刚遇到同样的问题。
我的解决方案是移动代码原生端。
在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以允许这种功能,如果我通过它就会回到这里。
答案 1 :(得分:1)
增强@ 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];
});
}
答案 2 :(得分:1)
我目前的解决方案。从技术上讲,这不是问题的直接答案,但提供了在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"];
答案 3 :(得分:-1)
我认为您可以使用实现AsyncStorage
中的代码来实现此目的。你可以看到它here。它基本上使用NSFileManager
加载存储数据的文件,然后相应地解析它们。在您的情况下,请查看multiGet
method处的实例,然后跟踪文件中存在的所有必需函数。有了它,您应该能够重新实施(或适应)以满足您的需求。