Доступ к данным, хранящимся в AsyncStorage, из собственного кода ios (цель c)

Мне нужно получить доступ к данным, хранящимся в AsyncStorage, из собственного кода Objective C. iOS.

Это необходимо, чтобы синхронизировать данные вместо отправки события приложения в JS, а затем отправить его обратно в собственный код.

Ответ 1

Я только что столкнулся с той же проблемой.

Мое решение состояло в том, чтобы переместить исходную сторону кода.

В 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 для выполнения этого синхронно

Update:

Мне нужна переменная в глобальном состоянии, а не только в компонентах реквизита, поэтому приведенное выше не достаточно далеко.

Мне пришлось работать в источнике React Native в том месте, где загружен источник Javascript.

NSString *javascriptPrepend = [NSString stringWithFormat:@"var ThemeMode = '%@';", self.theme];
NSMutableData *prependData = [[javascriptPrepend dataUsingEncoding:NSUTF8StringEncoding] mutableCopy];
[prependData appendData:sourceCode];

sourceCode = prependData; 

Я посмотрю, открыты ли они для PR, чтобы разрешить такую ​​функциональность и вернуться сюда, если я получу ее.

Ответ 2

Усовершенствование решения @lukes - устранение проблемы с расположением данных в 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];
  });
}

Ответ 3

Мое текущее решение. Что технически не является прямым ответом на вопрос, но предлагает обход для обмена данными между Javascript и собственным кодом, заключается в использовании NSUserDefaults.

Используя этот пакет, response-native-default-preferences, чтобы легко сохранить данные в NSUserdefaults, а затем на родной стороне легко восстановить их как обычно.

В моих целях я сохраняю токен, полученный в Javascript, который будет использоваться позже расширениями приложения. Это означает, что я также сохраняю пакет UserDefaults, используя тот же ключ, что и мое приложение.

React Native (Javascript):

DefaultPreference.setName('group.myApp');
DefaultPreference.set('TOKEN', token);

Objective-C:

NSString *TOKEN = [[[NSUserDefaults alloc] initWithSuiteName:@"group.myApp"] stringForKey:@"TOKEN"];

Ответ 4

Я думаю, что для этой цели вы можете использовать код из реализации AsyncStorage. Вы можете увидеть здесь здесь. Он в основном загружает файлы, хранящие данные, с помощью NSFileManager, а затем анализирует их соответственно. В вашем случае обратите внимание, например, на метод multiGet и затем проследите все необходимые функции, присутствующие в файле. С этим вы должны иметь возможность повторно реализовать их (или адаптировать) в соответствии с вашими потребностями.