使用 NSURLSession 处理 HTTP 错误的最佳实践?

Posted

技术标签:

【中文标题】使用 NSURLSession 处理 HTTP 错误的最佳实践?【英文标题】:Best practice to handle HTTP error with NSURLSession? 【发布时间】:2016-11-02 08:20:50 【问题描述】:

来自apple's doc- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error只会通过error参数报客户端错误。

注意:NSURLSession 不会通过 error 参数报告服务器错误。您的应用通过 error 参数收到的唯一错误是客户端错误,例如无法解析主机名或无法连接到主机。 URL 加载系统错误代码中描述了错误代码。 服务器端错误通过 NSHTTPURLResponse 对象中的 HTTP 状态代码报告。

但是,当我在 ios9 中使用 NSURLSessionDataTask 进行测试时,苹果目前似乎将一些 HTTP 错误映射到 NSURLError。例如,404 to NSURLErrorFileDoesNotExist。这个事实打破了我们之前的一些假设,many snippet also take the error parameter as connection error,这绝对是错误的。


我尝试搜索并发现Apple 可能只在NSURLSessionDownloadTask 中提到了此更改。并且没有很好地记录这些地图是如何应用的。

与 NSURLSessionDataTask 或 NSURLSessionUploadTask 不同,NSURLSessionDownloadTask 将通过 HTTP 状态码报告的服务器端错误报告到相应的 NSError 对象中。


我个人认为苹果的开发团队犯了一个很大的错误;而且文件仍然不一致,不真实,甚至两年过去了没有任何更新。

任何人都知道有关此更改的更多信息,何时引入?以及现在区分连接错误和 HTTP 错误的最佳方法是什么。

【问题讨论】:

试试看这个答案:***.com/questions/2342579/… 该链接的相关答案/讨论是什么? 【参考方案1】:

答案与往常一样。如果您的服务器发送带有 200 错误代码的错误(例如在 JSON 响应中),您必须自己处理该检查。否则:

如果您关心服务器发送的特定 HTTP 状态代码,请实现 didReceiveResponse 委托方法并拦截错误。 如果您只关心请求失败而不关心为什么,则可以保证通过完成回调中的错误参数得到一些错误,但不能保证得到任何特定的错误。

请注意,成功定义为:

结果代码 200(正常) 结果代码 304(未修改) 重定向到返回 200 或 304 的页面

如果您的定义不同(例如,如果您的服务器通过重定向到错误页面来响应无效 URL),您需要添加一个委托方法来检测重定向并将其视为错误。

【讨论】:

收到响应并不意味着它不会变成连接错误。我的问题是如何区分连接错误和HTTP错误,而不是状态码的含义。 如果在您收到服务器承诺的字节数(Content-Length)之前连接断开,您将收到 NSError。您可能会遇到三个错误之一,IIRC — NSURLErrorTimedOutSURLErrorNetworkConnectionLostNSURLErrorNotConnectedToInternet 文档中该措辞的目的不是表明服务器端错误永远不会生成 NSError 对象,而是表明它不能保证这样做。服务器端错误可以通过其他方式报告,例如在 JSON 字典中,通过重定向到带有 Fail Whale 的页面等,加载系统不一定能检测到所有这些。如果您的服务器以任何其他方式报告错误,或者如果服务器发回意外数据(例如 html 而不是 JSON),您的应用应该适当地检测到错误并做正确的事情。

以上是关于使用 NSURLSession 处理 HTTP 错误的最佳实践?的主要内容,如果未能解决你的问题,请参考以下文章

NSURLSession/NSURLConnection HTTP 加载失败 (kCFStreamErrorDomainSSL, -9802) 错误

NSURLSession 未下载完整数据,但成功完成

iOS NSURLSession 使用自定义委托处理数据任务的完成

使用 NSURLSession 异步下载数据和处理

如何使用 NSUrlsession 处理超过 1000 个 api 请求

NSURLSession HTTP/2 内存泄漏