我有一个函数需要等待一个完成处理程序的结果来返回一个BOOL,其值将在一个完成处理程序中设置:
-(BOOL) fetchFeed
{
......
NSURLSessionDataTask *dataTask =
[sharedSessionMainQueue dataTaskWithRequest:req completionHandler:
^(NSData *data, NSURLResponse *response, NSError *error){
NSMutableArray *jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:nil];
dispatch_async(dispatch_get_main_queue(), ^{
if(!jsonObject)
{
UIAlertAction *ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction *action){[self dismissViewControllerAnimated: YES completion: nil];}];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Connection problem." message:@"Please check your internet connection and trying logging in again." preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:ok];
[self presentViewController:alert animated:YES completion:nil];
_internetFailed = YES;
}
else
{
_internetFailed = NO;
}
});
}];
[dataTask resume];
return _internetFailed;
}
问题是现在_internetFailed在完成处理程序结束之前返回。我尝试将“return _internetFailed”移动到完成处理程序中,但这是不允许的。问题:我应该如何构造它以使返回等待完成处理程序的结束?
我环顾四周但在完成处理程序类型范例中找不到完成处理程序。还有哪些其他选择?提前感谢任何建议。
答案 0 :(得分:0)
首先,仅仅因为您没有JSON
对象并不意味着连接失败,您需要实际检查该信息的返回错误或运行reachability
检查。或者您可能刚刚获得了无效的JSON或任何其他错误。因此,您需要在决定向用户呈现的内容之前检查您收到的错误。
其次,此方法声明为void
,因此返回BOOL不是一个好主意。如果您想知道此任务的状态,请在调用站点的完成块中添加一些内容。通常,这样的方法只会直接返回任务,并允许在完成时处理任何其他行为。
以下是它的样子:
-(NSURLSessionDataTask *)fetchFeedWithCompletionBlock:(void (^)(NSArray *responseArray, NSError *error)completionBlock
{
....
NSURLSessionDataTask *dataTask = [sharedSessionMainQueue dataTaskWithRequest:req completionHandler:^(NSData *data, NSURLResponse *response, NSError *error){
//Check response status.
//Check error.
NSError *JSONError;
NSArray *jsonObject = [NSJSONSerialization JSONObjectWithData:data
options:0
error:&JSONError];
if (completionBlock) { // Check the completion block before calling, as calling a nil block will crash.
if (//Any error.) {
competionBlock(nil, error);
}
else {
completionBlock(responseArray, nil);
}
}
}
[dataTask resume];
return dataTask;
}
然后,如果此完成返回错误,您可以在调用站点上显示错误,如下所示:
[communicator fetchFeedWithCompletionBlock:^(NSArray *responseArray, NSError *error) {
if (error) {
// Present error.
}
else {
// Use array.
}
}];
此外,与任何类型的问题一样,我建议至少仔细阅读AFNetworking的来源或直接使用它。