在iOS中检测SIM卡的可能方法是什么?

7

我有一个 iPhone 应用程序,具有发送消息的功能。当 iPhone 没有可用的 SIM 卡时,我想要提醒用户。因此,我尝试了以下三个函数来检查 SIM 卡的可用性:

Class messageClass = (NSClassFromString(@"MFMessageComposeViewController"));
if([messageClass canSendText]){
    // Sim available
    NSLog(@"Sim available");
}
else{
    //Sim not available
    NSLog(@"Sim not available");
}

if([MFMessageComposeViewController canSendText]){
    // Sim available
    NSLog(@"Sim available");
}
else{
    //Sim not available
    NSLog(@"Sim not available");
}

if([[UIDevice currentDevice].model isEqualToString:@"iPhone"])
{
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel:123456"]])
    {
        NSLog(@"Sim available");
    }
    else
    {
        NSLog(@"Sim not available");
    }
}

我检查了没有插入sim卡的iphone,它总是显示“Sim可用”。但是,当我打开默认的“信息”应用程序并尝试发送短信时,它会弹出一个警告说“未安装SIM卡”...这个信息应用程序如何检测到sim卡的可用性?


1
我认为你做不到,因为苹果没有公开任何关于SIM卡、蜂窝网络、所在网络等方面的信息。 - nivritgupta
7个回答

10
您可以通过CTCarrier类进行检查。

enter image description here

BOOL isSimCardAvailable = YES;

CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = info.subscriberCellularProvider;

if(carrier.mobileNetworkCode == nil || [carrier.mobileNetworkCode isEqualToString:@""])
{
    isSimCardAvailable = NO;
}

你需要添加 CoreTelephony 框架来使用 CTTelephonyNetworkInfo 和 CTCarrier。


7

通过下面的代码,您可以获取SIM卡的详细信息,例如运营商名称、移动国家代码、ISO国家代码、移动网络代码。在iOS 6中,所有这些信息都会被保留。因此,即使您拔出了SIM卡,它仍将保留旧的详细信息。但是,在iOS 7中,只有运营商名称被保留,其余信息都发生了变化,因此可以使用下面的代码。

CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = info.subscriberCellularProvider;
NSString *mobileCountryCode = carrier.mobileCountryCode;
NSString *carrierName = carrier.carrierName;
NSString *isoCountryCode = carrier.isoCountryCode;
NSString *mobileNetworkCode = carrier.mobileNetworkCode

// Try this to track CTCarrier changes 
info.subscriberCellularProviderDidUpdateNotifier = ^(CTCarrier* inCTCarrier) {
        dispatch_async(dispatch_get_main_queue(), ^{
            NSLog(@"User did change SIM");
        });
};

据我所知,在iOS中没有办法通过这种方法检测SIM卡是否存在。但是你使用的代码也应该可以正常工作。我不知道为什么它没有正常工作? - Balaji Sabdhar M
消息应用程序是什么意思? - Balaji Sabdhar M
不行。但我认为这是不可能的。这个应用程序已经默认安装在iPhone上了。我们怎么能得到那个源代码呢?因此,在iPhone上有更多的默认应用程序,如Safari、App Store、地图等。 - vinoth kannan
我发现了一种未记录的方法,可以检测iPhone中SIM卡的可用性。NSString * CTSIMSupportGetSIMStatus(); int CTGetSignalStrength();NSString *status = CTSIMSupportGetSIMStatus();NSLog(@"Sim卡状态 %@",status); - vinoth kannan
1
https://dev59.com/Z3rZa4cB1Zd3GeqP4p6H#24367325 - Aneeq Anwar
显示剩余3条评论

6

以Swift实现为只读计算属性:

import CoreTelephony

var availableSIM: Bool {
    return CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode != nil
}

3
补充Anneq和Felipe的回答: Swift 2.3:
import CoreTelephony
func isSimAvailable()  -> Bool {
    let info = CTTelephonyNetworkInfo()
    let carr = info.subscriberCellularProvider
    guard let carrier = carr else {
        return false
    }
    guard let carrierCode = carrier.mobileNetworkCode else {
        return false
    }
    guard carrierCode != "" else {
        return false
    }
    return true
}

2

补充Anneq Anwar的回答,这里是Swift版本:

import CoreTelephony
func isSimAvailable()  -> Bool {
    var isSimCardAvailable = true
    var info = CTTelephonyNetworkInfo()
    var carrier = info.subscriberCellularProvider
    if carrier != nil && carrier.mobileNetworkCode == nil || carrier.mobileNetworkCode.isEqual("") {
        isSimCardAvailable = false
    }
    return isSimCardAvailable
}

修复:在某些设备上,承运人可能为空。

1
嘿,莱昂纳多,看起来根据设备的不同,运营商可能为空,谢谢啊;D - Felipe R. Saruhashi

1
Swift 4+。
var isSimCardAvailable: Bool {

    let info = CTTelephonyNetworkInfo()
    if let carrier = info.subscriberCellularProvider {
        if let code = carrier.mobileNetworkCode {
            if !code.isEmpty {
                return true
            }
        }
    }
    return false
}

0

覆盖常规SIM卡和eSIM的Swift 5+解决方案

    func hasCellularCoverage() -> Bool {
        let networkInfo = CTTelephonyNetworkInfo()

        guard let serviceSubscriberCellularProviders = networkInfo.serviceSubscriberCellularProviders else { return false }
        let carriers = serviceSubscriberCellularProviders.values

        let validCarriers = carriers.compactMap() {
            $0.isoCountryCode
        }

        return !validCarriers.isEmpty ? true : false
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接