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

iOS中如何获取无线电信号服务状态(类似Android ServiceState)

iOS 中实现类似 Android TelephonyManager.ServiceState 的服务状态判断

我明白你想要在iOS上实现和Android TelephonyManager里ServiceState一样的功能,区分当前蜂窝无线电信号的状态是in_service、out_of_service还是emergency_only。你已经搞定了无线电接入技术的获取,但卡在服务状态的判断上,下面给你几个可行的思路和代码实现方向:

核心思路:结合多维度指标推断状态

iOS并没有直接提供和Android ServiceState一一对应的API,所以我们需要结合网络注册状态、蜂窝可达性、紧急呼叫能力这几个维度来综合判断。

方法1:利用 CoreTelephony 框架检测运营商注册状态

你已经在使用CTTelephonyNetworkInfo获取无线电技术,我们可以扩展它,通过CTCarrier的信息判断设备是否已注册到蜂窝网络:

import CoreTelephony

func getCellularServiceState() -> String {
    let networkInfo = CTTelephonyNetworkInfo()
    // 获取当前所有蜂窝服务提供商(适配双卡设备)
    guard let cellularProviders = networkInfo.serviceSubscriberCellularProviders else {
        return "out_of_service"
    }
    
    for carrier in cellularProviders.values {
        // 当mobileNetworkCode和mobileCountryCode非空时,说明设备已注册到运营商网络
        let isRegisteredToNetwork = carrier.mobileNetworkCode != nil && carrier.mobileCountryCode != nil
        if isRegisteredToNetwork {
            // 进一步判断是否仅支持紧急呼叫:结合VOIP权限+网络可达性
            let isEmergencyOnly = carrier.allowsVOIP == false && !isCellularNetworkReachable()
            return isEmergencyOnly ? "emergency_only" : "in_service"
        }
    }
    
    // 没有任何运营商注册的情况
    return "out_of_service"
}

// 辅助方法:检测蜂窝网络是否可达
private func isCellularNetworkReachable() -> Bool {
    let monitor = NWPathMonitor(requiredInterfaceType: .cellular)
    var isReachable = false
    let semaphore = DispatchSemaphore(value: 0)
    
    monitor.pathUpdateHandler = { path in
        isReachable = path.status == .satisfied
        semaphore.signal()
        monitor.cancel()
    }
    monitor.start(queue: DispatchQueue.global())
    semaphore.wait()
    
    return isReachable
}

方法2:用 Network 框架检测蜂窝可达性+紧急呼叫能力

iOS 12+ 引入的Network框架可以更精准地检测网络状态,结合紧急呼叫的可用性来区分状态:

import Network
import UIKit

func checkServiceState(completion: @escaping (String) -> Void) {
    let cellularMonitor = NWPathMonitor(requiredInterfaceType: .cellular)
    
    cellularMonitor.pathUpdateHandler = { path in
        defer { cellularMonitor.cancel() }
        
        switch path.status {
        case .satisfied:
            // 蜂窝网络正常可用,属于in_service
            completion("in_service")
        case .unsatisfied:
            // 网络不可用时,检查是否能拨打紧急号码
            let canMakeEmergencyCalls = UIApplication.shared.canOpenURL(URL(string: "tel:911")!)
            completion(canMakeEmergencyCalls ? "emergency_only" : "out_of_service")
        case .requiresConnection:
            // 等待连接中,暂时归为out_of_service
            completion("out_of_service")
        @unknown default:
            completion("out_of_service")
        }
    }
    
    cellularMonitor.start(queue: DispatchQueue.global(qos: .background))
}

注意:使用canOpenURL检测紧急号码时,需要在Info.plist中添加tel的URL Scheme权限,否则会返回false。

额外注意事项

  • 双卡设备需要遍历所有蜂窝服务提供商,不能只取第一个
  • emergency_only的判断可能因地区、运营商和设备型号有差异,建议在目标场景下做实际测试
  • 可以监听CTTelephonyNetworkInfo的serviceSubscriberCellularProvidersDidUpdateNotifier通知,实时更新服务状态

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:51:53