我有一个方法,该方法通常在本地返回一个字符串,但带有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并不是最好的方法,但是我正在努力避免很多身份验证开销。
答案 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
,则需要小心。