如何 return 异步 json 请求的结果

How to return result of asynchronous json request

我有一个方法,通常在本地 returns 字符串,但有来自 Web 的备份。我正在使用 dataWithContentsOfUrl 检索一些 JSON,但想切换到使用对 UI 更好的 Session 对象,而且——如果我没记错的话——允许服务器在phone,但是,我正在努力解决异步问题。

使用旧代码,我刚刚返回了 JSON,但我正在为如何为异步结果执行此操作而苦苦挣扎。我无法更改 returns 字符串的调用方法。我可以用异步 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 对象的情况下在 phone 上设置一个 sessionID?我知道设置会话 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,则需要小心。