iOS应用退后台时调用Alamofire发起请求出现网络连接丢失错误如何解决
错误产生原因
- iOS 系统对进入后台的应用进程有严格的资源限制,默认会在应用退后台3秒左右冻结进程,回收网络连接资源,未完成的前台网络请求会直接被中断,因此抛出
NSURLErrorDomain Code=-1005 "The network connection was lost"报错 - 当前代码使用的Alamofire默认请求基于前台
URLSession配置,不支持后台执行,请求生命周期和应用前台状态绑定 - 代码没有向系统申请额外的后台执行时长,退后台后进程被冻结前请求无法完成
解决方案
针对单次短耗时的后台网络请求,最简便的方案是向系统申请临时后台执行权限,等请求完成后主动结束后台任务,修改后的代码如下:
- 首先在当前类中声明后台任务标识属性:
// 存储后台任务标识 var backgroundTaskID: UIBackgroundTaskIdentifier = .invalid
- 调整退后台的网络请求逻辑:
@objc func appMovedToBackground() { // 向系统申请后台执行时间,回调是系统告知可用时间即将耗尽时的兜底处理 backgroundTaskID = UIApplication.shared.beginBackgroundTask(withName: "SingleBackgroundRequest") { [weak self] in guard let self = self else { return } if self.backgroundTaskID != .invalid { UIApplication.shared.endBackgroundTask(self.backgroundTaskID) self.backgroundTaskID = .invalid } } let requestURL: String = "http://www.test.com/" AF.request(requestURL, method: .post, parameters: parameters, headers: headers) .responseJSON { [weak self] response in guard let self = self else { return } switch response.result { case .success(let data): print(data) case .failure(let error): print(error) } // 请求处理完成后主动结束后台任务,释放系统资源 if self.backgroundTaskID != .invalid { UIApplication.shared.endBackgroundTask(self.backgroundTaskID) self.backgroundTaskID = .invalid } } }
额外注意事项
- 如果你的请求耗时较长(超过系统分配的最大临时后台时长,通常为30秒),需要使用Alamofire的后台会话配置
URLSessionConfiguration.background(withIdentifier: "com.yourapp.backgroundSession")初始化会话,支持长时间后台网络任务 - 由于iOS ATS安全策略默认拦截HTTP请求,你需要在Info.plist中为请求的HTTP域名添加例外,否则请求会直接被系统拦截
- 后台任务使用完成必须主动调用
endBackgroundTask,否则超过系统允许的执行时长会被系统直接杀死应用进程
内容的提问来源于stack exchange,提问作者tomtript
相关产品推荐
相关产品推荐

