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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 11:15:33