代码之家  ›  专栏  ›  技术社区  ›  user6631314

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

  •  0
  • user6631314  · 技术社区  · 6 年前

    我有一个方法,通常在本地返回一个字符串,但是有一个来自Web的备份。我使用dataWithContentsOfUrl检索了一些JSON,但是我想切换到使用一个会话对象,这对UI更好,而且——如果我没有弄错的话——允许服务器在电话上设置一个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不是最好的方法,但我正在尝试避免大量的身份验证开销。

    0 回复  |  直到 6 年前
        1
  •  1
  •   Aaron    6 年前

    可以将块传递给异步函数,然后在调用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 在街区的任何地方。