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
相关产品推荐
相关产品推荐

