使用Alamofire.SessionManager实现重试与离线管理时遇离线回调异常
解决Alamofire离线时responseData回调不触发的问题
我之前开发时也碰到过一模一样的问题!Alamofire默认的SessionManager在完全离线的情况下,确实不会触发responseData这类回调——这是因为底层的URLSession在检测到没有网络连接时,会把请求挂起等待网络恢复,而不是立即返回错误。下面是我当时试过的几个有效解决方案:
1. 给Session配置超时时间,强制触发错误回调
默认的URLSession超时时间很长,离线时请求会一直挂着不返回。我们可以自定义Session的配置,缩短超时时间,让请求在离线时快速超时,从而触发回调:
// 创建自定义配置 let config = URLSessionConfiguration.default config.timeoutIntervalForRequest = 8 // 请求超时时间(秒) config.timeoutIntervalForResource = 8 // 资源加载超时时间(秒) // 用自定义配置初始化SessionManager let customSession = Alamofire.SessionManager(configuration: config) // 用这个自定义Session发起请求 customSession.request("https://www.google.pl").responseData(queue: queue) { response in print(response) // 离线时会在这里拿到超时错误 }
2. 提前监听网络状态,避免无效请求
可以用Alamofire自带的NetworkReachabilityManager在发起请求前判断网络状态,如果离线直接走失败逻辑,不用发起请求:
let reachability = Alamofire.NetworkReachabilityManager(host: "www.google.pl") reachability?.startListening { status in switch status { case .notReachable: print("当前离线,直接处理失败逻辑") // 这里可以调用你原本在responseData里的失败处理代码 case .reachable(_): // 网络正常,发起请求 Alamofire.SessionManager.default.request("https://www.google.pl") .responseData(queue: queue) { response in print(response) } case .unknown: // 网络状态未知,可选择发起请求或提示用户 Alamofire.SessionManager.default.request("https://www.google.pl") .responseData(queue: queue) { response in print(response) } } }
3. 自定义重试策略,结合网络状态控制请求走向
实现RequestRetrier协议,在重试逻辑里判断网络状态,离线时直接终止请求并触发回调:
class OfflineRetryPolicy: RequestRetrier { func should(_ manager: SessionManager, retry request: Request, with error: Error, completion: @escaping RequestRetryCompletion) { // 检查当前网络状态 guard let reachable = manager.reachabilityManager?.isReachable else { // 状态未知,不重试 completion(false, 0) return } if !reachable { // 离线,直接失败,不重试 completion(false, 0) } else { // 其他错误,可选择重试(比如重试1次) completion(true, 1) } } } // 给默认Session设置自定义重试策略 Alamofire.SessionManager.default.retrier = OfflineRetryPolicy() // 发起请求,离线时会触发失败回调 Alamofire.SessionManager.default.request("https://www.google.pl") .responseData(queue: queue) { response in print(response) }
额外注意点
你的代码里请求的URL是"www.google.pl",记得加上协议头https://,否则Alamofire可能无法正确处理请求,这也可能是导致回调异常的隐藏原因哦!
内容的提问来源于stack exchange,提问作者mike bob
相关产品推荐
相关产品推荐

