You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

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

火山引擎 最新活动