Swift 4中如何处理HTTP load failed(错误码-1009 [1:50])避免APP崩溃?
解决网络请求错误(error code: -1009)导致的APP崩溃问题
我之前在Xcode 9用Swift 4开发的时候也碰到过一模一样的问题!这个-1009错误其实就是系统在告诉你:当前设备没有连接到互联网。你的APP崩溃,大概率是因为没有捕获这个错误,就直接去解析不存在的JSON数据了——毕竟没网络的话,请求根本拿不到返回数据,强行解析肯定会崩。
下面给你一步步讲怎么解决:
1. 先捕获错误,判断错误码
在你的登录请求回调里,一定要先检查是否有错误返回,并且精准判断是不是无网络的错误。这里用URLSession的请求示例给你写代码:
let loginUrl = URL(string: "你的登录接口地址")! var loginRequest = URLRequest(url: loginUrl) loginRequest.httpMethod = "POST" // 这里设置你的请求体参数,比如账号密码的JSON数据 let params = ["username": "xxx", "password": "xxx"] loginRequest.httpBody = try? JSONSerialization.data(withJSONObject: params) let task = URLSession.shared.dataTask(with: loginRequest) { data, response, error in // 第一步:优先处理错误 if let requestError = error as NSError? { // 判断是不是无网络错误(NSURLErrorNotConnectedToInternet对应的code就是-1009) if requestError.code == NSURLErrorNotConnectedToInternet { // 弹窗提示用户,注意UI操作必须在主线程! DispatchQueue.main.async { let alert = UIAlertController(title: "网络异常", message: "当前没有可用网络,请检查你的网络连接", preferredStyle: .alert) alert.addAction(UIAlertAction(title: "知道了", style: .default)) // 获取当前最上层的ViewController来弹出弹窗 if let topViewController = UIApplication.shared.keyWindow?.rootViewController { topViewController.present(alert, animated: true) } } return // 直接返回,不要再往下执行解析逻辑了! } else { // 处理其他类型的请求错误,比如服务器报错等 print("请求出错:\(requestError.localizedDescription)") return } } // 第二步:确认有数据后再解析JSON guard let responseData = data else { print("请求没有返回任何数据") return } do { let loginResult = try JSONSerialization.jsonObject(with: responseData, options: []) // 这里处理登录成功的逻辑,比如保存用户信息、跳转到首页 DispatchQueue.main.async { // 更新UI的操作必须在主线程 print("登录成功:\(loginResult)") // 比如self.navigationController?.pushViewController(HomeVC(), animated: true) } } catch { print("JSON解析出错:\(error.localizedDescription)") } } task.resume()
2. 关键注意点:UI操作必须在主线程
网络请求的回调是在后台线程执行的,如果你直接在后台线程弹出弹窗,要么不显示,要么会导致异常。所以一定要用DispatchQueue.main.async把弹窗的代码包起来,确保在主线程执行。
3. 可选优化:提前检查网络状态(非必须,但更友好)
如果你想在用户点击登录按钮时就先检查网络,避免发起无效请求,可以用系统的SCNetworkReachability来做网络检测(因为Xcode 9对应的iOS版本是11,NWPathMonitor是iOS 12才出的,所以用这个更兼容)。不过要注意,即使提前检查了网络,也可能在请求发起后网络突然断开,所以捕获请求错误的步骤还是不能少,这是最可靠的崩溃防护手段。
最后再提醒一下:一定要确保在拿到错误后就return,终止后续的解析逻辑,这样就不会因为没有数据去解析而崩溃了。
内容的提问来源于stack exchange,提问作者mab




