Лучшая практика для обработки ошибок HTTP с помощью NSURLSession?

Из документа Apple - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error будут доступны только сообщить об ошибке на стороне клиента через параметр ошибки.

Примечание. NSURLSession не сообщает об ошибках сервера с помощью параметра error. Единственными ошибками, которые ваше приложение получает с помощью параметра error, являются ошибки на стороне клиента, такие как невозможность разрешить имя хоста или подключиться к хосту. Коды ошибок описаны в разделе Коды ошибок системы загрузки URL. Об ошибках на стороне сервера сообщается с помощью кода состояния HTTP в объекте NSHTTPURLResponse.

Но, однако, когда я тестирую iOS9 с NSURLSessionDataTask, кажется, что в настоящее время Apple сопоставляет некоторую ошибку HTTP с NSURLError. Например, 404 to NSURLErrorFileDoesNotExist. Этот факт опровергает некоторые предположения, которые у нас были раньше, и многие фрагменты также принимают параметр ошибки как ошибку соединения, это будет абсолютно неправильно.


Я пытаюсь найти и обнаружил, что Apple может упомянуть это изменение только в NSURLSessionDownloadTask. И не очень хорошо задокументировано, как эти карты применяются.

В отличие от NSURLSessionDataTask или NSURLSessionUploadTask, NSURLSessionDownloadTask сообщает об ошибках на стороне сервера, сообщаемых с помощью кодов состояния HTTP, в соответствующие объекты NSError.


Лично я считаю, что команда разработчиков Apple совершила большую ошибку; И документ по-прежнему противоречив и не актуален, даже два года прошло без каких-либо обновлений.

У кого-нибудь есть дополнительная информация об этом изменении, когда оно будет введено? И как сейчас лучше всего отличить ошибку подключения от ошибки HTTP.


person Karl    schedule 02.11.2016    source источник
comment
попробуйте посмотреть этот ответ: stackoverflow.com/questions/2342579/   -  person Wink    schedule 02.11.2016
comment
каков соответствующий ответ / обсуждение по этой ссылке?   -  person marosoaie    schedule 02.11.2016


Ответы (1)


Ответ тот же, что и всегда. Если ваш сервер отправляет ошибки с кодом ошибки 200 (например, в ответе JSON), вам придется самостоятельно обрабатывать эту проверку. В противном случае:

  • Если вам важно, какой конкретный код состояния HTTP отправляет сервер, реализуйте метод делегата didReceiveResponse и перехватите ошибку.
  • Если вас заботит только то, что запрос не выполнен, и вас не волнует, почему, вы гарантированно получите некоторую ошибку через параметр error в обратном вызове завершения, но не гарантируете, что получите какую-либо конкретную ошибку. ошибка.

Обратите внимание, что успех определяется как любое из:

  • Код результата 200 (ОК)
  • Код результата 304 (НЕ ИЗМЕНЕН)
  • Редирект на страницу, которая возвращает 200 или 304

Если ваше определение отличается (например, если ваш сервер отвечает на недопустимые URL-адреса, перенаправляя на страницу с ошибкой), вам необходимо добавить метод делегата для обнаружения перенаправления и обработки его как ошибки.

person dgatwood    schedule 02.11.2016
comment
Получение ответа не означает, что он не приведет к ошибке подключения. Мои вопросы заключаются в том, как отличить ошибку соединения и ошибку HTTP, а не в значении кода состояния. - person Karl; 03.11.2016
comment
Если соединение обрывается до того, как вы получите количество байтов, обещанное сервером (Content-Length), вы получите NSError. Вы можете получить одну из трех ошибок, IIRC — либо NSURLErrorTimedOut, либо SURLErrorNetworkConnectionLost, либо NSURLErrorNotConnectedToInternet. - person dgatwood; 03.11.2016
comment
Цель этой формулировки в документации заключалась не в том, чтобы указать, что ошибка на стороне сервера никогда не будет генерировать объект NSError, а в том, чтобы указать, что это не гарантировано. Об ошибке на стороне сервера можно сообщить другими способами, например, в словаре JSON, через перенаправление на страницу с Fail Whale и т. д., не все из которых обязательно могут быть обнаружены системой загрузки. Если ваш сервер сообщает об ошибках каким-либо из этих способов или если сервер отправляет обратно неожиданные данные (например, HTML вместо JSON), ваше приложение должно соответствующим образом обнаружить ошибку и поступить правильно. - person dgatwood; 03.11.2016