iOS 16中CTCarrier废弃后,如何检测设备是否存在SIM卡?
iOS 16+ 下替代SIM卡检测实现设备认证的方案
针对iOS 16中CTCarrier废弃导致无法直接检测SIM卡存在性的问题,以下是几个可行的替代方案,适配支付类应用的设备认证需求:
方案1:通过无线接入技术状态判断SIM卡是否存在
利用CTTelephonyNetworkInfo的serviceCurrentRadioAccessTechnology属性,该属性会返回当前各蜂窝服务的无线接入技术类型。当设备无SIM卡时,对应的条目会为空,据此可以判断SIM卡状态:
import CoreTelephony func hasSIMCard() -> Bool { let networkInfo = CTTelephonyNetworkInfo() if #available(iOS 12.0, *) { guard let radioTechs = networkInfo.serviceCurrentRadioAccessTechnology else { return false } // 遍历所有服务,只要有一个存在有效接入技术则判定有SIM卡 for (_, tech) in radioTechs { if tech != nil { return true } } return false } else { // iOS 12以下沿用旧逻辑 return networkInfo.subscriberCellularProvider != nil } }
方案2:结合蜂窝网络连接状态验证
使用Network框架的NWPathMonitor检测蜂窝网络是否可用,无SIM卡时蜂窝网络必然无法建立有效连接,可作为辅助判断手段:
import Network func isCellularNetworkAvailable() async -> Bool { let monitor = NWPathMonitor(requiredInterfaceType: .cellular) let semaphore = DispatchSemaphore(value: 0) var isAvailable = false monitor.pathUpdateHandler = { path in isAvailable = path.status == .satisfied && path.usesInterfaceType(.cellular) semaphore.signal() monitor.cancel() } let queue = DispatchQueue(label: "CellularConnectivityMonitor") monitor.start(queue: queue) semaphore.wait() return isAvailable }
注意:该方法存在局限性——若设备有SIM但无信号,也会返回
false,建议和其他方案结合使用。
方案3:改造原有运营商信息获取逻辑,增加SIM状态判断
针对你提供的原有代码,可修改为同时返回SIM卡存在状态。在iOS 16+中,当SIM卡被移除时,serviceSubscriberCellularProviders会返回空字典,据此可以判断:
import CoreTelephony func simOperatorFor(name: String?, code: String?) -> (operatorName: String, operatorCode: String, hasSIM: Bool) { var operatorName = "defaultOperator" var operatorCode = "" var hasSIM = false let networkInfo = CTTelephonyNetworkInfo() if #available(iOS 12.0, *) { guard let carriers = networkInfo.serviceSubscriberCellularProviders, !carriers.isEmpty else { return (operatorName, operatorCode, false) } hasSIM = true for key in carriers.keys { operatorName = carriers[key]?.carrierName ?? "defaultOperator" operatorCode = carriers[key]?.mobileNetworkCode ?? "" if let existingName = name, let existingCode = code, !existingName.isEmpty, !existingCode.isEmpty { if operatorName == existingName && operatorCode == existingCode { break } } else { if !operatorName.isEmpty && !operatorCode.isEmpty { break } } } } else { guard let carrier = networkInfo.subscriberCellularProvider else { return (operatorName, operatorCode, false) } hasSIM = true operatorName = carrier.carrierName ?? "defaultOperator" operatorCode = carrier.mobileNetworkCode ?? "" } return (operatorName, operatorCode, hasSIM) }
调用时通过返回的hasSIM字段判断是否需要展示「未找到SIM卡」提示。
额外建议:优化支付类应用的设备认证逻辑
单一的SIM卡检测安全性有限,建议结合以下方式提升认证可靠性:
- 设备标识符(IDFV,需符合Apple隐私政策)
- 生物识别验证(Touch ID/Face ID)
- 应用内的设备绑定逻辑
内容的提问来源于stack exchange,提问作者Jaini
相关产品推荐
相关产品推荐

