Swift中如何监听iOS蜂窝网络连接类型变化(无需轮询)
在Swift中监听蜂窝网络连接类型变化(无需轮询)
iOS 14+ 推荐方案:使用NWPathMonitor
Network框架的NWPathMonitor是Apple官方推荐的网络状态监听方案,可直接获取蜂窝网络的接入技术类型,无需轮询即可收到状态变化通知。
实现步骤
- 导入
Network框架 - 创建
NWPathMonitor实例,可指定仅监听蜂窝网络 - 设置路径更新回调,在回调中解析当前蜂窝接入技术类型
- 启动监控并指定处理队列
- 在页面销毁或不需要监听时停止监控,避免内存泄漏
代码示例
import UIKit import Network class ViewController: UIViewController { // 持有监视器实例,防止被提前释放 private var cellularMonitor: NWPathMonitor? private let monitorQueue = DispatchQueue(label: "CellularNetworkMonitorQueue") override func viewDidLoad() { super.viewDidLoad() setupCellularMonitoring() } private func setupCellularMonitoring() { // 创建仅监听蜂窝网络的监视器 cellularMonitor = NWPathMonitor(requiredInterfaceType: .cellular) cellularMonitor?.pathUpdateHandler = { [weak self] path in guard path.usesInterfaceType(.cellular) else { DispatchQueue.main.async { self?.updateStatus(text: "未连接蜂窝网络") } return } guard let accessTech = path.cellularAccessTechnology else { return } let techName: String switch accessTech { case .nr: techName = "5G (NR)" case .lte: techName = "4G (LTE)" case .umts: techName = "3G (UMTS)" case .edge: techName = "2G (Edge)" case .gprs: techName = "2G (GPRS)" default: techName = "未知蜂窝类型" } DispatchQueue.main.async { self?.updateStatus(text: "当前蜂窝类型:\(techName)") } } // 启动监控 cellularMonitor?.start(queue: monitorQueue) } private func updateStatus(text: String) { // 这里可替换为UI更新逻辑,比如更新UILabel文本 print(text) } deinit { // 停止监控释放资源 cellularMonitor?.cancel() } }
iOS 14 以下兼容方案:使用CoreTelephony
若需支持iOS14之前的系统,可使用CoreTelephony框架,通过监听系统通知获取网络类型变化。注意必须持有CTTelephonyNetworkInfo的强引用,否则会因实例被释放而收不到通知。
代码示例
import UIKit import CoreTelephony class ViewController: UIViewController { // 强引用持有,确保通知能正常触发 private let networkInfo = CTTelephonyNetworkInfo() override func viewDidLoad() { super.viewDidLoad() setupCellularNotification() // 初始化时获取当前网络类型 checkCurrentCellularTech() } private func setupCellularNotification() { NotificationCenter.default.addObserver( self, selector: #selector(cellularTechChanged(_:)), name: .CTRadioAccessTechnologyDidChange, object: nil ) } @objc private func cellularTechChanged(_ notification: Notification) { checkCurrentCellularTech() } private func checkCurrentCellularTech() { guard let currentTech = networkInfo.serviceCurrentRadioAccessTechnology?.values.first else { print("未连接蜂窝网络") return } let techName: String switch currentTech { case CTRadioAccessTechnologyNR: techName = "5G (NR)" case CTRadioAccessTechnologyLTE: techName = "4G (LTE)" case CTRadioAccessTechnologyWCDMA, CTRadioAccessTechnologyHSDPA, CTRadioAccessTechnologyHSUPA, CTRadioAccessTechnologyCDMAEVDORev0, CTRadioAccessTechnologyCDMAEVDORevA, CTRadioAccessTechnologyCDMAEVDORevB, CTRadioAccessTechnologyeHRPD: techName = "3G" case CTRadioAccessTechnologyEdge, CTRadioAccessTechnologyGPRS: techName = "2G (Edge/GPRS)" default: techName = "未知蜂窝类型" } print("当前蜂窝类型:\(techName)") } deinit { NotificationCenter.default.removeObserver(self) } }
注意事项
- 使用
CoreTelephony时,serviceCurrentRadioAccessTechnology是字典类型,对应多SIM卡场景,示例中取第一个SIM卡的网络类型,可根据需求调整。 - 部分网络类型常量会随iOS版本更新,需根据目标系统版本适配。
内容的提问来源于stack exchange,提问作者KannonLyriq
相关产品推荐
相关产品推荐

