I have a iphone app that has the capability to send messages. I want to alert user when sim card is not available in iphone. So i tried below three function to check sim card availabilty
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");
}
}
I have checked my iphone without sim, it always return @"Sim available". But when i open default "Messages" app and try to send sms it says alert "No SIM Card Installed"... How this message app can detect sim card availabilty?
By the below code you can get the sim card details like carriername,mobilecountrycode,isocountrycode,mobilenetworkcode.In the ios 6 all are retained.So if your sim card is removed also it will retain the old details.So there this idea wont be useful but in ios 7 only carriername is retained and remaining are changed so the below code can be used
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");
});
};
You can check it by CTCarrier class.
BOOL isSimCardAvailable = YES;
CTTelephonyNetworkInfo* info = [[CTTelephonyNetworkInfo alloc] init];
CTCarrier* carrier = info.subscriberCellularProvider;
if(carrier.mobileNetworkCode == nil || [carrier.mobileNetworkCode isEqualToString:@""])
{
isSimCardAvailable = NO;
}
You need to add CoreTelephony framework for using CTTelephonyNetworkInfo and CTCarrier.
Implemented in Swift as a read-only computed property:
import CoreTelephony
var availableSIM: Bool {
return CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode != nil
}
Complementing to Anneq and Felipe answers:
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
}
Complementing the Anneq Anwar answer, here the swift version:
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
}
fix: The carrier can be nil in some devices