操作系统错误是由数据包没有到达预定目标导致的. 数据包可能是建立连接的一部分, 也可能位于连接建立的中间阶段. OS 错误可能由如下原因造成:
- 没有网络 - 如果设备没有数据网络连接, 那么连接尝试很快就会被拒绝或是失败. 这些类型的错误可以通过 Apple 提供的 Reachability 框架检测到
- 无法路由到目标主机 - 设备可能有网络连接, 不过连接的目标可能位于隔离的网络中或是处于离线状态. 这些错误有时可以由操作系统迅速检测到, 不过也有可能导致连接超时.
- 没有应用监听目标端口 - 在请求到达目标主机后, 数据包会被发送到请求指定的端口号. 如果没有服务器监听这个端口或是有太多的连接请求在排队, 那么连接请求就会被拒绝
- 无法解析目标主机名 - 如果无法解析目标主机名, 那么 URL 加载系统就会返回错误. 通常情况下, 这些错误是由配置错误或是尝试访问没有外部名字解析且处于隔离网络中的主机造成的在 iOS 的 URL 加载系统中, 操作系统错误会以 NSError 对象的形式发送给应用. iOS 通过 NSError 在软件组件间传递错误信息. 相比简单的错误代码来说, 使用 NSError 的主要优势在于 NSError 对象包含了错误域属性.
不过, NSError 对象的使用并不限于操作系统. 应用可以创建自己的 NSError 对象, 使用它们在应用内传递错误消息. 如下代码片段展示的应用方法使用 NSError 向调用的视图控制器传递回失败信息:
域属性根据产生错误代码的库或框架对这些错误代码进行隔离. 借助域, 框架开发者无须担心覆盖错误代码, 因为域属性定义了产生错误的框架. 比如, 框架 A 与 B 都会产生错误代码 1, 不过这两个错误代码会被每个框架提供的唯一域值进行区分. 因此, 如果代码需要区分 NSError 值, 就必须对 NSError对象的 code 与 domain 属性进行比较.
- code - 标识错误的 NSInteger 值. 对于产生该错误的错误域来说, 这个值是唯一的
- domain - 指定错误域的 NSString 指针, 比如 NSPOSIXErrorDomain、NSOSStatusErrorDomain 及 NSMachErrorDomain.
- userInfo - NSDictionary 指针, 其中包含特定于错误的值URL 加载系统中产生的很多错误都来自于 NSURLErrorDomain 域, 代码值基本上都来自于 CFNetworkErrors.h 中定义的错误代码. 与 iOS 提供的其他常量值一样, 代码应该使用针对错误定义好的常量名而不是实际的错误代码值.
在每次发起网络连接前检查一下网络状态
iOS 的 SystemConfiguration 框架提供了多种方式来确定设备的网络连接状态
Reachability 封装器提供如下 4 个主要功能:
- 标识设备是否具备可用的网络连接
- 标识当前的网络连接是否可以达到某个特定的主机
- 标识当前使用的是哪种网络技术: Wi-Fi、WWAN 还是什么技术都没用
- 在网络状态发生变化时发出通知使用 Reachability:
- 下载 Reachability API , 把 Reachability.h/.m 添加到应用 Xcode 项目中
- SystemConfiguration 框架添加