Использование RCTAsyncLocalStorage + getAllKeys

Я пытаюсь получить собственный код AsyncStorage для iOS. Итак, это мой код

- (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];
                }
            }
        }

        @try {
            NSData *jsonAsData = [jsonAsString dataUsingEncoding:NSUTF8StringEncoding];

            NSError *error;

            NSDictionary *json = [
              NSJSONSerialization
              JSONObjectWithData:jsonAsData
              options:NSJSONReadingMutableContainers
              error:&error
            ];

            completion(json, error);
        }
        @catch (NSException *exception) {
            NSLog(@"error: %@", exception.reason);

            NSMutableDictionary * info = [NSMutableDictionary dictionary];
            [info setValue:exception.name forKey:@"ExceptionName"];
            [info setValue:exception.reason forKey:@"ExceptionReason"];
            [info setValue:exception.callStackReturnAddresses forKey:@"ExceptionCallStackReturnAddresses"];
            [info setValue:exception.callStackSymbols forKey:@"ExceptionCallStackSymbols"];
            [info setValue:exception.userInfo forKey:@"ExceptionUserInfo"];

            NSError *error = [[NSError alloc] initWithDomain:@"" code:1 userInfo:info];

            completion(nil, error);
        }
    };

    // RCTAsyncLocalStorage *storage = [RCTAsyncLocalStorage new];
    RCTAsyncLocalStorage *storage = [[RCTAsyncLocalStorage alloc] init];

    dispatch_async(storage.methodQueue, ^{
        @try {
            // [storage performSelector:@selector(multiGet:callback:) withObject:@[key] withObject:rnCompletion];
            [storage performSelector:@selector(getAllKeys:callback:) withObject:rnCompletion];
        }
        @catch (NSException *exception) {
            NSLog(@"error: %@", exception.reason);
        }
    });
}

Когда я пытаюсь получить один из своих ключей (multiGet)

[self jsonFromLocalRNStrogeForKey:@"session" completion:^(NSDictionary* data,NSError* error) {
    if (data) {
        NSString * name = [data valueForKeyPath: @"token"];
        if (![name isKindOfClass:[NSNull class]]) {
            [self reportIncomingCallFrom:name withUUID:callInvite.uuid];
        }
    } else {
        NSLog(@"error: JSON Parsing Error: %@",error.localizedFailureReason);
    }
}];

Я всегда получаю ноль

введите здесь описание изображения

И когда я пытаюсь получить все ключи (...@selector(getAllKeys:...), чтобы посмотреть, что у меня есть в моем AsyncStorage, я получаю исключение

@"NSInvalidArgumentException" - reason: @"-[RCTAsyncLocalStorage getAllKeys:callback:]: unrecognized selector sent to instance 0x1085512c0"

RN имеет RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)callback) в RCTAsyncLocalStorage.m; но в RCTAsyncLocalStorage.h (void)getAllKeys:(RCTResponseSenderBlock)callback его нет, и даже его добавление не работает (https://github.com/facebook/react-native/blob/master/React/Modules/RCTAsyncLocalStorage.h).


"react-native": "^0.48.4",

Как вернуть NSJsonSerialization


person Pablo    schedule 16.01.2018    source источник


Ответы (1)


Во-первых,

RN имеет RCT_EXPORT_METHOD(getAllKeys:(RCTResponseSenderBlock)обратный вызов) в RCTAsyncLocalStorage.m; но в обратном вызове RCTAsyncLocalStorage.h (void) getAllKeys: (RCTResponseSenderBlock) его не существует

В Objective-C вы можете вызвать метод, даже если он не объявлен в заголовочном файле с помощью performSelector:withObject:.

Вызов этого метода напрямую (без предварительной проверки цели respondsToSelector:) является плохой практикой, так как объявление внутреннего метода может измениться.

Во-вторых, эта строка неверна:

[storage performSelector:@selector(getAllKeys:callback:) withObject:rnCompletion];

Здесь вы говорите, что getAllKeys:: принимает два аргумента, однако реализация объявляет только один.

Следовательно, правильный способ извлечения всех ключей следующий:

dispatch_async(storage.methodQueue, ^{

    if([storage respondsToSelector:@selector(getAllKeys:)]){
        [storage performSelector:@selector(getAllKeys:) withObject:[^(NSArray* response){
            NSLog(@"Contents: %@",response);
        } copy]];
    }else{
        NSLog(@"storage does not respond to selector `getAllKeys:`");
    }

});
person W.K.S    schedule 16.01.2018
comment
Так что, даже не заявленный в шапке, я все равно смогу получить доступ к getAllKeys? Вот что я получаю от Xcode: Нет видимого @interface для 'RCTAsyncLocalStorage' объявляет селектор 'getAllKeys:' - person Pablo; 16.01.2018
comment
Рад, что смог помочь :) - person W.K.S; 16.01.2018