如何返回异步JSON请求的结果

时间:2019-03-07 00:11:58

标签: ios asynchronous nsurlsession

我有一个方法,该方法通常在本地返回一个字符串,但带有Web备份。我正在使用dataWithContentsOfUrl检索一些JSON,但想切换到使用对UI更好的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";
}

将感谢您的任何建议。

如果我完全不想做,是否可以在没有Session对象的情况下在电话上设置sessionID?我知道设置会话ID并不是最好的方法,但是我正在努力避免很多身份验证开销。

1 个答案:

答案 0 :(得分:1)

您可以将一个块传递给异步函数,然后在调用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,则需要小心。