| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 |
- //
- // 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) }
- }
- }
|