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

Swift网络自动重连实现:优化断网提示为自动恢复无需重启

嘿,我懂你要的效果——现在你的代码只是在某个时机单次检测网络状态,断网时弹个提示,但没法自动察觉到网络恢复并重新连接对吧?咱们把它改成实时监听网络状态变化就搞定了,完全不用用户重启应用。

实现网络状态实时监听与自动重连

你当前的代码逻辑是“一次性判断网络”,要实现断网后自动感知恢复并执行重连,核心是改成持续监听网络状态的变化,下面给你两种可行的方案:

方案一:基于你当前用的Reachability库

1. 先保存Reachability实例(避免被提前释放)

在你的ViewController(或者专门的网络管理类)里声明一个全局的Reachability对象:

import Reachability

class YourViewController: UIViewController {
    private var reachability: Reachability!
    private var isNoNetworkAlertShowing = false // 用来避免重复弹弹窗
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupNetworkMonitoring()
    }
}

2. 配置监听与状态回调

注册网络状态变化的通知,让应用能实时收到网络切换的信号:

private func setupNetworkMonitoring() {
    do {
        reachability = try Reachability()
        // 监听网络状态变化通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleNetworkStatusChange(_:)),
            name: .reachabilityChanged,
            object: reachability
        )
        try reachability.startNotifier()
    } catch {
        print("启动网络监听失败:\(error.localizedDescription)")
    }
}

// 网络状态变化时触发的方法
@objc private func handleNetworkStatusChange(_ notification: Notification) {
    guard let reachability = notification.object as? Reachability else { return }
    
    switch reachability.connection {
    case .wifi, .cellular:
        print("网络恢复啦!")
        // 在这里执行你的自动重连逻辑:比如重新请求接口、刷新页面
        autoReconnect()
    case .unavailable:
        print("网络断开了")
        // 弹出断网提示(用标记控制,避免重复弹窗)
        showNoNetworkAlert()
    case .none:
        break
    }
}

// 自动重连逻辑(根据你的业务需求自定义)
private func autoReconnect() {
    // 示例:重新加载列表数据
    // yourDataManager.reloadData()
    // self.tableView.reloadData()
    
    // 或者重新初始化你的网络请求客户端
    // yourAPIClient.resetAndReconnect()
}

// 断网提示弹窗
private func showNoNetworkAlert() {
    guard !isNoNetworkAlertShowing else { return }
    isNoNetworkAlertShowing = true
    
    let alert = UIAlertController(
        title: "提示",
        message: "当前无网络连接,请检查你的网络设置",
        preferredStyle: .alert
    )
    let okAction = UIAlertAction(title: "知道了", style: .default) { _ in
        self.isNoNetworkAlertShowing = false
    }
    alert.addAction(okAction)
    present(alert, animated: true)
}

// 记得在页面销毁时清理监听,防止内存泄漏
deinit {
    reachability.stopNotifier()
    NotificationCenter.default.removeObserver(self, name: .reachabilityChanged, object: nil)
}

方案二:使用iOS系统自带的NWPathMonitor(无需第三方库)

如果不想依赖第三方Reachability库,iOS 12及以上可以直接用系统的Network框架实现监听:

import Network

class YourViewController: UIViewController {
    private var networkMonitor: NWPathMonitor!
    private let monitorQueue = DispatchQueue(label: "NetworkStatusMonitor")
    private var isNoNetworkAlertShowing = false
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupSystemNetworkMonitor()
    }
    
    private func setupSystemNetworkMonitor() {
        networkMonitor = NWPathMonitor()
        networkMonitor.pathUpdateHandler = { [weak self] path in
            // 网络回调在后台线程,更新UI要切回主线程
            DispatchQueue.main.async {
                if path.status == .satisfied {
                    print("网络恢复!")
                    self?.autoReconnect()
                } else {
                    print("网络断开")
                    self?.showNoNetworkAlert()
                }
            }
        }
        networkMonitor.start(queue: monitorQueue)
    }
    
    // 这里的autoReconnect和showNoNetworkAlert方法和方案一完全一样,直接复用即可
    
    deinit {
        networkMonitor.cancel()
    }
}

几个关键注意点

  • 避免重复弹窗:一定要加isNoNetworkAlertShowing这类标记,不然网络状态频繁波动时会弹出一堆重复的提示框。
  • 主线程更新UI:网络监听的回调默认在后台线程,所有涉及UI操作的代码(弹窗、刷新界面)必须切回主线程。
  • 清理监听资源:在页面销毁时停止监听、移除通知/取消monitor,防止内存泄漏。

这样修改后,你的应用就能实时感知网络状态变化,断网时弹一次提示,网络恢复后自动执行重连逻辑,完全不需要用户手动重启应用~

内容的提问来源于stack exchange,提问作者William Loke

火山引擎 最新活动