首页 > 解决方案 > 如何返回异步json请求的结果

问题描述

我有一个方法,通常在本地返回一个字符串,但有来自 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 不是最好的方法,但我试图避免大量的身份验证开销。

标签: iosasynchronousnsurlsession

解决方案


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


推荐阅读