2014-12-04 3 views
0

У меня есть функция, которая должна ждать результата обработчика завершения возвратить BOOL, для которого значение будет установлено внутри обработчика завершения:подождать до конца обработчика завершения, чтобы вернуть 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

Вы можете использовать семафор – Andy

+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. 
    } 
}]; 

Кроме того, как любой вопрос с типом I рекомендую по крайней мере использовать источник для AFNetworking или использовать его напрямую.

+0

Благодарим за информацию. Функция BOOL - это была опечатка выше, но спасибо за то, что она тоже указана. –