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

iOS开发:如何获取实体SIM卡数据而非eSIM,或读取双SIM信息检测运营商

解决iOS上优先读取实体SIM卡或检测特定运营商SIM的问题

首先,你的问题核心在于CTTelephonyNetworkInfo的serviceSubscriberCellularProviders是一个无序字典,直接取first或values.first并不能保证拿到实体SIM的数据——iOS会根据当前主卡优先级或激活顺序返回条目,这就是为什么只有实体SIM设为主卡时才能得到预期结果。

针对你的核心需求:检测用户是否使用Free Mobile(MCC 208 / MNC 15)SIM卡

最可靠的方法是遍历所有可用的蜂窝服务条目,直接匹配目标MCC和MNC,不管该SIM是实体还是eSIM。这样既绕开了实体/ eSIM的区分问题,又能精准达成你的检测目标。

修改后的代码如下:

import CoreTelephony

func checkForFreeMobileSIM() {
    let telephonyInfo = CTTelephonyNetworkInfo()
    
    // 获取所有蜂窝服务的运营商信息
    guard let allCarriers = telephonyInfo.serviceSubscriberCellularProviders else {
        print("无法获取蜂窝服务信息")
        return
    }
    
    var targetCarrier: CTCarrier?
    var targetRadioTech: String?
    
    // 遍历所有服务,匹配Free Mobile的MCC和MNC
    for (serviceId, carrier) in allCarriers {
        guard let mcc = carrier.mobileCountryCode, let mnc = carrier.mobileNetworkCode else {
            continue
        }
        
        if mcc == "208" && mnc == "15" {
            targetCarrier = carrier
            // 获取对应的无线接入技术并格式化
            if let rawTech = telephonyInfo.serviceCurrentRadioAccessTechnology?[serviceId] {
                targetRadioTech = rawTech.replacingOccurrences(of: "CTRadioAccessTechnology", with: "", options: .literal)
            }
            break // 找到第一个匹配的SIM即可,如需检测所有匹配项可移除break
        }
    }
    
    // 输出结果
    if let carrier = targetCarrier {
        print("检测到Free Mobile SIM卡:")
        print("- 运营商名称:\(carrier.carrierName ?? "未知")")
        print("- MCC:\(carrier.mobileCountryCode ?? "未知")")
        print("- MNC:\(carrier.mobileNetworkCode ?? "未知")")
        print("- ISO国家码:\(carrier.isoCountryCode?.uppercased() ?? "未知")")
        print("- 当前无线接入技术:\(targetRadioTech ?? "未知")")
    } else {
        print("未检测到Free Mobile SIM卡")
    }
}

如果确实需要优先读取实体SIM卡数据

iOS没有公开的API直接区分实体SIM和eSIM,但可以通过CTCellularPlanManager获取已激活的eSIM计划的服务ID,然后从蜂窝服务列表中排除这些ID,剩下的就是实体SIM的信息:

import CoreTelephony

// 获取所有eSIM的服务标识符
private func getESIMServiceIdentifiers() -> [String] {
    let planManager = CTCellularPlanManager()
    guard let activePlans = planManager.plans else { return [] }
    return activePlans.compactMap { $0.serviceIdentifier }
}

func getPhysicalSIMInfo() {
    let telephonyInfo = CTTelephonyNetworkInfo()
    guard let allCarriers = telephonyInfo.serviceSubscriberCellularProviders else {
        print("无法获取蜂窝服务信息")
        return
    }
    
    let eSIMServiceIds = getESIMServiceIdentifiers()
    // 筛选出实体SIM的服务条目
    let physicalSIMCarriers = allCarriers.filter { !eSIMServiceIds.contains($0.key) }
    
    if let physicalCarrier = physicalSIMCarriers.values.first {
        print("实体SIM卡信息:")
        print("- 运营商名称:\(physicalCarrier.carrierName ?? "未知")")
        print("- MCC:\(physicalCarrier.mobileCountryCode ?? "未知")")
        print("- MNC:\(physicalCarrier.mobileNetworkCode ?? "未知")")
        print("- ISO国家码:\(physicalCarrier.isoCountryCode?.uppercased() ?? "未知")")
        
        // 获取对应的无线接入技术
        if let serviceId = physicalSIMCarriers.keys.first,
           let rawTech = telephonyInfo.serviceCurrentRadioAccessTechnology?[serviceId] {
            let formattedTech = rawTech.replacingOccurrences(of: "CTRadioAccessTechnology", with: "", options: .literal)
            print("- 当前无线接入技术:\(formattedTech)")
        }
    } else {
        print("未检测到实体SIM卡")
    }
}

注意事项

  • 确保在Info.plist中添加NSCellularDataUsageDescription,描述应用需要访问蜂窝数据信息的原因,否则应用会被拒绝访问这些API。
  • CTCellularPlanManager的部分功能在iOS 12+可用,需要注意版本兼容性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:32:33