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

iOS内部Flutter应用获取蜂窝网络详细信息的方案咨询

问题描述

我正在开发一款内部Flutter移动应用,需要在iOS端获取信号强度(dBm)、小区ID(CID)、位置区域码(LAC)等详细蜂窝网络信息。已知iOS公开API限制此类信息访问,但应用仅作内部使用,寻求可行解决方案。

当前使用的Swift代码(CoreTelephony实现):

import Foundation
import CoreTelephony

class RfSignalStrengthImpl: RfSignalStrengthApi {
    func getCellularSignalStrength(completion: @escaping (Result<CellularSignalStrength, Error>) -> Void) {
        let networkInfo = CTTelephonyNetworkInfo()

        guard let carrier = networkInfo.serviceSubscriberCellularProviders?.values.first else {
            completion(.failure(NSError(domain: "com.xxxx.yyyy", code: 0, userInfo: [NSLocalizedDescriptionKey: "Carrier not found"])))
            return
        }

        let carrierName = carrier.carrierName ?? "Unknown"
        let mobileCountryCode = carrier.mobileCountryCode ?? "Unknown"
        let mobileNetworkCode = carrier.mobileNetworkCode ?? "Unknown"
        let radioAccessTechnology = networkInfo.serviceCurrentRadioAccessTechnology?.values.first ?? "Unknown"

        var connectionStatus = "Unknown"
        if let radioTech = networkInfo.currentRadioAccessTechnology {
            switch radioTech {
            case CTRadioAccessTechnologyGPRS:
                connectionStatus = "GPRS"
            case CTRadioAccessTechnologyEdge:
                connectionStatus = "EDGE"
            case CTRadioAccessTechnologyCDMA1x:
                connectionStatus = "CDMA1x"
            case CTRadioAccessTechnologyCDMAEVDORev0:
                connectionStatus = "EvDo Rev. 0"
            case CTRadioAccessTechnologyCDMAEVDORevA:
                connectionStatus = "EvDo Rev. A"
            case CTRadioAccessTechnologyHSDPA:
                connectionStatus = "HSDPA"
            case CTRadioAccessTechnologyHSUPA:
                connectionStatus = "HSUPA"
            case CTRadioAccessTechnologyLTE:
                connectionStatus = "LTE"
            default:
                connectionStatus = "Unknown"
            }
        }

        let duplexMode = "Unknown"
        let level: Int64 = -1
        let dbm: Int64 = -1
        let rssi: Int64 = -1
        let rsrq: Int64 = -1

        let cid: Int64 = -1
        let lac: Int64 = -1

        let response = CellularSignalStrength(
            level: level,
            dbm: dbm,
            rssi: rssi,
            rsrq: rsrq,
            cid: cid,
            lac: lac,
            carrierName: carrierName,
            mobileCountryCode: mobileCountryCode,
            mobileNetworkCode: mobileNetworkCode,
            radioAccessTechnology: radioAccessTechnology,
            connectionStatus: connectionStatus,
            duplexMode: duplexMode
        )
        completion(.success(response))
    }
}

当前输出结果:

{
    level: -1,
    dbm: -1,
    rssi: -1,
    rsrq: -1,
    cid: -1,
    lac: -1,
    carrierName: --,
    mobileCountryCode: 65535,
    mobileNetworkCode: 65535,
    radioAccessTechnology: CTRadioAccessTechnologyLTE,
    connectionStatus: LTE,
    duplexMode: Unknown
}

核心问题:

  • 如何在iOS内部应用中获取详细蜂窝网络信息(信号强度、CID、LAC等)?
  • CoreTelephony已被弃用,替代方案是什么?

解决方案

一、使用CoreTelephony的现代公开API

CoreTelephony并未完全废弃,仅旧版API标记为过时。iOS 12+提供了CTCellularSignalStrength系列API,可获取信号相关参数:

  1. 权限配置:在Info.plist中添加NSCellularNetworkUsageDescription,说明应用需要蜂窝网络权限的原因。
  2. 信号强度获取示例:
import CoreTelephony

func fetchSignalStrength() {
    let networkInfo = CTTelephonyNetworkInfo()
    guard let signalStrength = networkInfo.cellSignalStrength else { return }
    
    // 按网络类型获取对应参数
    if let lteStrength = signalStrength as? CTLTESignalStrength {
        let rssi = lteStrength.rssi // RSSI(dBm)
        let rsrq = lteStrength.rsrq // RSRQ(dB)
        let rsrp = lteStrength.rsrp // RSRP(dBm)
        let sinr = lteStrength.sinr // SINR(dB)
        print("LTE信号参数:RSSI=\(rssi), RSRQ=\(rsrq), RSRP=\(rsrp), SINR=\(sinr)")
    } else if let gsmStrength = signalStrength as? CTGSMSignalStrength {
        let rssi = gsmStrength.rssi
        print("GSM信号RSSI:\(rssi) dBm")
    }
    // CDMA、5G等网络类型可同理处理
}

限制:公开API无法获取CID、LAC,仅能拿到信号量化参数。

二、使用私有API(仅内部应用适用)

因应用不通过App Store分发,可尝试调用iOS私有框架API获取CID、LAC:

  1. 利用Runtime访问CTCarrier私有属性:
import CoreTelephony
import ObjectiveC

extension CTCarrier {
    var cellId: Int? {
        return self.value(forKey: "cellId") as? Int
    }
    var locationAreaCode: Int? {
        return self.value(forKey: "locationAreaCode") as? Int
    }
}

// 使用示例
let networkInfo = CTTelephonyNetworkInfo()
if let carrier = networkInfo.serviceSubscriberCellularProviders?.values.first {
    if let cid = carrier.cellId {
        print("CID: \(cid)")
    }
    if let lac = carrier.locationAreaCode {
        print("LAC: \(lac)")
    }
}
  1. 注意事项:
    • 私有API随iOS版本更新可能失效,需针对不同版本适配。
    • 打包时关闭Bitcode,避免编译报错。
    • 应用需使用企业证书签名以实现内部分发。

三、变通方案:位置服务+基站数据库匹配

若私有API风险过高,可通过间接方式获取近似信息:

  1. 启用位置服务获取当前GPS坐标。
  2. 结合离线/自建基站数据库,根据坐标匹配对应CID、LAC及信号强度信息。
    限制:数据精度依赖基站数据库的完整性,无法获取设备端实时信号参数。

四、Flutter端桥接注意事项

  1. 通过MethodChannel实现Flutter与iOS原生代码的通信,将获取到的蜂窝信息传递至Dart层。
  2. 确保原生端权限配置完整,包括蜂窝网络权限、位置权限(若使用变通方案)。
  3. 针对不同iOS版本做兼容性处理,避免API变更导致崩溃。

内容的提问来源于stack exchange,提问作者RAITON

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 01:27:32