Как вернуть результат асинхронного json-запроса - PullRequest
0 голосов
/ 07 марта 2019

У меня есть метод, который возвращает строку обычно локально, но с резервной копией из Интернета. Я извлекал JSON с использованием dataWithContentsOfUrl, но хочу переключиться на использование объекта Session, который лучше подходит для пользовательского интерфейса, а также - если я не ошибаюсь - позволяет серверу установить sessionId на телефоне, однако я изо всех сил с асинхронной проблемой.

Со старым кодом я только что возвратил JSON, но я борюсь с тем, как сделать это для асинхронного результата. Я не могу изменить вызывающий метод, который возвращает строку. Что я могу сделать с асинхронным вызовом Api, чтобы использовать полученные данные?

асинхронный:

-(void)getAsyncAnswerFor:(NSString*) str {
    NSString *surl = [NSString stringWithFormat: @"https://~.com//api.php?q=%@",str];
    NSURL *url = [NSURL URLWithString:surl];
    NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
                                          dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
  //HOW DO I PASS THIS BACK TO THE CALLING METHOD OR IS THAT IMPOSSIBLE
                                          }];

    [downloadTask resume];
}

синхронизация

-(NSString*)getAnswerFor:(NSString*) str {
    NSError *error;
    NSString *surl = [NSString stringWithFormat: @"https://~.com//api.php?q=%@",str];
    NSData *data = [NSData dataWithContentsOfURL: [NSURL URLWithString:surl]];
    NSMutableArray *json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
   //process JSON
    if (error) {
    return @"";
    }
    return @"processed JSON";
}

Буду признателен за любые предложения.

Если то, что я хочу сделать, абсолютно невозможно, возможно ли установить sessionID на телефоне без объекта Session? Я знаю, что установка идентификатора сеанса - не самый лучший подход, но я стараюсь избежать больших затрат на аутентификацию.

1 Ответ

1 голос
/ 07 марта 2019

Вы можете передать блок асинхронной функции и затем вызвать его при вызове обработчика завершения сеанса URL. Это тривиальный пример:

- (void)doSomethingWithBlock:(void (^)(double, double))block {
    ...
    block(21.0, 2.0);
}

Я поднял этот ^^ из Apple Docs , но вы могли бы сделать что-то вроде этого: (Примечание: я не проверял это в компиляторе!)

-(void)getAsyncAnswerFor:(NSString*) str completion:(void (^)(NSData, NSURLResponse, NSError))block {
    NSString *surl = [NSString stringWithFormat: @"https://~.com//api.php?q=%@",str];
    NSURL *url = [NSURL URLWithString:surl];
    NSURLSessionDataTask *downloadTask = [[NSURLSession sharedSession]
                                          dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
                                             block(data, response, error);
                                          }];

    [downloadTask resume];
}

Вам нужно быть осторожным, если вы попытаетесь сослаться на self в любом месте блоков.

...