You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS Swift 4:如何基于Reachability.swift全局监听网络连接状态

全局统一实现网络状态监听方案

针对你提到的「40余个类重复实现Reachability监听」的问题,最优雅的方式是把网络状态管理逻辑封装成单例工具类,全局统一初始化和监听,需要感知状态的页面只需要订阅通知即可,完全避免重复代码。

步骤1:创建单例网络状态管理器

把Reachability的配置、状态监听、通知发送逻辑全部封装在这里,确保全局只有一个监听实例:

import Foundation
import Reachability

class NetworkManager {
    // 全局单例实例
    static let shared = NetworkManager()
    
    private var reachability: Reachability!
    
    // 定义清晰的网络状态枚举,方便外部调用
    enum NetworkStatus {
        case connected
        case disconnected
    }
    
    // 私有初始化方法,保证单例唯一性
    private init() {
        do {
            reachability = try Reachability()
        } catch {
            print("Reachability初始化失败:\(error.localizedDescription)")
            return
        }
        
        // 监听网络可达状态变化
        reachability.whenReachable = { [weak self] _ in
            self?.broadcastNetworkStatus(.connected)
        }
        
        // 监听网络不可达状态变化
        reachability.whenUnreachable = { [weak self] _ in
            self?.broadcastNetworkStatus(.disconnected)
        }
        
        // 启动监听
        do {
            try reachability.startNotifier()
        } catch {
            printReachability启动监听失败:\(error.localizedDescription)")
        }
    }
    
    // 发送网络状态变化通知
    private func broadcastNetworkStatus(_ status: NetworkStatus) {
        NotificationCenter.default.post(
            name: .networkStatusChanged,
            object: status
        )
    }
    
    // 提供外部获取当前网络状态的方法
    func getCurrentStatus() -> NetworkStatus {
        return reachability.connection != .unavailable ? .connected : .disconnected
    }
    
    deinit {
        reachability.stopNotifier()
    }
}

// 给通知名称扩展全局常量,避免硬编码
extension NSNotification.Name {
    static let networkStatusChanged = NSNotification.Name("NetworkStatusChanged")
}

步骤2:在AppDelegate中初始化管理器

只需要在App启动时触发单例初始化,让监听逻辑自动启动:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 初始化网络管理器,自动开始全局监听
    _ = NetworkManager.shared
    return true
}

步骤3:在目标页面监听状态变化

比如你的DashboardVC,只需要订阅通知并处理状态即可,无需重复配置Reachability:

class DashboardVC: UIViewController {
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        // 注册网络状态通知
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleNetworkStatusChange(_:)),
            name: .networkStatusChanged,
            object: nil
        )
        
        // 页面出现时先获取一次当前状态,做初始化处理
        let currentStatus = NetworkManager.shared.getCurrentStatus()
        updateUI(for: currentStatus)
    }
    
    override func viewWillDisappear(_ animated: Bool) {
        super.viewWillDisappear(animated)
        // 页面消失时移除通知监听,避免内存泄漏
        NotificationCenter.default.removeObserver(
            self,
            name: .networkStatusChanged,
            object: nil
        )
    }
    
    @objc private func handleNetworkStatusChange(_ notification: Notification) {
        guard let status = notification.object as? NetworkManager.NetworkStatus else { return }
        updateUI(for: status)
    }
    
    // 具体的状态处理逻辑,根据业务需求自定义
    private func updateUI(for status: NetworkManager.NetworkStatus) {
        switch status {
        case .connected:
            print("网络已连接,可刷新数据或隐藏无网络提示")
            // 比如:self.refreshData() / self.noNetworkView.isHidden = true
        case .disconnected:
            print("网络已断开,显示无网络提示或暂停请求")
            // 比如:self.noNetworkView.isHidden = false
        }
    }
}

额外优化技巧

如果项目中大部分页面都需要处理网络状态,可以创建一个BaseViewController基类,把通知的注册/移除逻辑放在基类中,子类只需要重写updateUI(for:)方法即可,进一步减少重复代码。

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:19:06