我有一种通常在本地返回字符串的方法,但并带有网络备份。我正在使用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
,则需要小心。