// // LNNetworkMonitor.swift // Lanu // // Created by OneeChan on 2025/11/2. // import Foundation import Network import CoreTelephony protocol LNNetworkMonitorNotify { func onNetworkStateChanged(state: LNNetworkState) } extension LNNetworkMonitorNotify { func onNetworkStateChanged(state: LNNetworkState) {} } enum LNNetworkState { case noNetwork case available } enum LNNetworkType { case unknown // 未知 case notConnected // 无网络 case wifi // WiFi case cellular2G // 2G case cellular3G // 3G case cellular4G // 4G case cellular5G // 5G var desc: String { switch self { case .unknown: "unknown" case .notConnected: "unknown" case .wifi: "wifi" case .cellular2G: "2g" case .cellular3G: "3g" case .cellular4G: "4g" case .cellular5G: "5g" } } } class LNNetworkMonitor { // 创建网络路径监听器(可指定监听的网络类型,如 .cellular、.wifi 等,nil 表示监听所有类型) private static let monitor = NWPathMonitor() // 蜂窝网络信息管理器 private static let telephonyInfo = CTTelephonyNetworkInfo() // 用于在主线程处理回调 private static let queue = DispatchQueue(label: "LNNetworkMonitor") private(set) static var curState: LNNetworkState = .noNetwork { didSet { if oldValue != curState { notifyNeetworkStateChanged() } } } static func startMonitoring() { // 设置路径变化的回调 monitor.pathUpdateHandler = { path in // 检查当前网络的授权状态 switch path.status { case .satisfied: // 网络已连接(可能已授权) curState = .available case .unsatisfied: // 网络未连接(可能因授权问题导致) Log.d("网络未连接,可能未授权或无网络") curState = .noNetwork case .requiresConnection: // 正在连接中(可能需要等待授权) Log.d("正在连接网络...") curState = .noNetwork @unknown default: Log.d("未知网络状态") curState = .noNetwork } // // 更精确的授权状态判断(通过 path.isExpensive 等属性辅助判断) // if path.isExpensive { // print("当前网络为蜂窝网络或付费网络") // } // // // 检查是否受限于低数据模式 // if path.isConstrained { // print("网络受限于低数据模式") // } } // 开始监听(指定处理队列) monitor.start(queue: queue) } // 停止监听(例如在页面销毁时调用) static func stopMonitoring() { monitor.cancel() } static var curNetworkType: LNNetworkType { let path = monitor.currentPath guard path.status == .satisfied else { return .notConnected } if path.usesInterfaceType(.wifi) { return .wifi } if path.usesInterfaceType(.cellular) { return cellularNetworkType } return .unknown } static var networkProvider: String { if let carriers = telephonyInfo.serviceSubscriberCellularProviders { // 遍历所有 SIM 卡的网络类型(取第一个有效类型) for (_, carrier) in carriers { if let name = carrier.carrierName, !name.isEmpty { return name } } } return "" } private static var cellularNetworkType: LNNetworkType { if let serviceRadioMap = telephonyInfo.serviceCurrentRadioAccessTechnology { // 遍历所有 SIM 卡的网络类型(取第一个有效类型) for (_, radioType) in serviceRadioMap { return mapRadioTypeToNetworkType(radioType) } } return .unknown } // 映射无线电类型到网络类型 private static func mapRadioTypeToNetworkType(_ radioType: String) -> LNNetworkType { switch radioType { // 2G 类型 case CTRadioAccessTechnologyGPRS, CTRadioAccessTechnologyEdge, CTRadioAccessTechnologyCDMA1x: return .cellular2G // 3G 类型 case CTRadioAccessTechnologyWCDMA, CTRadioAccessTechnologyHSDPA, CTRadioAccessTechnologyHSUPA, CTRadioAccessTechnologyCDMAEVDORev0, CTRadioAccessTechnologyCDMAEVDORevA, CTRadioAccessTechnologyCDMAEVDORevB, CTRadioAccessTechnologyeHRPD: return .cellular3G // 4G LTE case CTRadioAccessTechnologyLTE: return .cellular4G // 5G(iOS 14.1+ 支持) case CTRadioAccessTechnologyNR: return .cellular5G default: return .unknown } } } extension LNNetworkMonitor { private static func notifyNeetworkStateChanged() { LNEventDeliver.notifyEvent { ($0 as? LNNetworkMonitorNotify)?.onNetworkStateChanged(state: curState) } } }