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



我有一种通常在本地返回字符串的方法,但并带有网络备份。我正在使用datawithcontentsofurl检索一些JSON,但想切换到使用一个会话对象,该对象对UI更好,并且(如果我没记错的话)使服务器允许在电话上设置SessionID,但是,我正在努力与异步问题有关。

使用旧的代码,我刚刚返回了JSON,但我正在为如何处理异步结果而苦苦挣扎。我无法更改返回字符串的调用方法。我该如何处理使用检索到的数据的异步API调用?

async:

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

会感谢任何建议。

如果我想做的完全不可能,那么如果没有会话对象,是否可以在手机上设置会话ID?我知道设置会话ID不是最伟大的方法,但是我试图避免大量身份验证开销。

您可以将块传递到异步功能,然后在调用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,则需要小心。

最新更新