Обрабатывать ошибки при асинхронной загрузке данных под IOS5 - PullRequest
0 голосов
/ 17 января 2012

Я новичок в программировании на iOS. В моем тестовом приложении я хотел бы загрузить некоторые XML-данные с сервера и сделать из них аннотации. Он прекрасно работает, и в качестве следующего шага я изменил его на асинхронный путем отправки.

Все отлично работает, но я не знаю, как обрабатывать исключения в этом сценарии? Куда / как обращаться, если сервер недоступен? Где / как обращаться, если нет сетевого подключения? Где / как обрабатывать время ожидания соединения?

Мой тестовый код выглядит так:

dispatch_queue_t downloadQueue = dispatch_queue_create("test data fetcher", NULL);
dispatch_async(downloadQueue, ^{
    NSString* fetchedXML = [Fetcher getTestData:@"http://127.0.0.1:11111"];
    dispatch_async(dispatch_get_main_queue(), ^{
        NSArray *annotations = [TestAnnotation getFromXML:fetchedXML];
        self.annotations = annotations;
    });
});
dispatch_release(downloadQueue);

самая важная часть метода getTestData в Fetcher

NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
NSURLResponse *response = nil;
NSError *error = nil;

NSData *responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
NSString *responseString = [[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding];

Заранее спасибо!

Ответы [ 2 ]

1 голос
/ 17 января 2012

Ну, хотя это не имеет прямого отношения к вашему вопросу, вы можете рассмотреть возможность использования встроенных средств асинхронного запроса NSURLConnection вместо того, чтобы использовать собственные методы с dispatch_async (), используя либо + sendAsynchronousRequest: queue: завершение :handHandler:, либо - initWithRequest: делегат:.

В вашем случае из документации по методу:

"Возвращает nil, если не удалось создать соединение или произошла ошибка загрузки."

Итак, у вас есть такая идиома, как:

if (responseData) {
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
}
else {
    // Read error and handle appropriately.  To see the error on the console, for example:
    NSLog(@"%@", [error localizedDesription]);
}

Главное, что следует помнить об этом (и всех других случаях, когда передается NSError **), заключается в том, что вы никогда сначала не прочитали значение ошибки, чтобы увидеть, произошел ли сбой. Вы проверяете его только после того, как вам сообщили (в данном случае, имея nil responseData), что возникла ошибка.

P.S.- В Objective-C «исключение» конкретно относится к ошибке программиста, поэтому использование «исключения» для описания сбоя сети некорректно. Это будет просто ошибка времени выполнения, которая, как ожидается, будет обработана в ходе обычной деятельности.

1 голос
/ 17 января 2012

Вы передаете NSURLResponse и NSError по ссылке на sendSynchronous селектор NSURLConnection.Когда этот селектор вернется, эти объекты будут заполнены данными, которые вы ищете.

1) Вместо передачи NSURLResponse, передайте NSHTTPURLResponse, который является подклассом, который позволит вам проверять код состояния HTTP (response.statusCode) для кодов, отличных от 200.

2) Проверкачтобы увидеть, является ли возвращаемое значение sendSynchronous нулевым, и проверить объект NSError на предмет информации об ошибке.Это где тайм-ауты и другие проблемы с подключением появятся.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...