Ios 检测设备是否支持电话呼叫?

Ios 检测设备是否支持电话呼叫?,ios,objective-c,iphone,cocoa-touch,phone-call,Ios,Objective C,Iphone,Cocoa Touch,Phone Call,以下代码用于确定设备是否支持电话呼叫是否可靠? 我担心的是,如果苹果将iphone字符串更改为其他内容,比如说他们决定使用“iPhone3G”、“iPhone4”等 我认为你的方法不可靠,因为设备名称将来可能会改变。如果您担心应用程序无法在非iPhone设备上运行,您可以在Info.plist中将“电话”添加到字典中。这将禁止iPhone以外的设备从应用商店下载你的应用 或者,如果您需要在特定时刻检查3G连接,您可以使用Apple的实用程序类询问当前3G/WIFI连接状态。iPhone支持tel

以下代码用于确定设备是否支持电话呼叫是否可靠? 我担心的是,如果苹果将iphone字符串更改为其他内容,比如说他们决定使用“iPhone3G”、“iPhone4”等


我认为你的方法不可靠,因为设备名称将来可能会改变。如果您担心应用程序无法在非iPhone设备上运行,您可以在Info.plist中将“电话”添加到字典中。这将禁止iPhone以外的设备从应用商店下载你的应用


或者,如果您需要在特定时刻检查3G连接,您可以使用Apple的实用程序类询问当前3G/WIFI连接状态。

iPhone支持tel://URI方案。因此,您可以使用:

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
canOpenURL:显式检查是否存在能够打开该URL方案的应用程序,而不是检查URL是否正确。因此,没有指定电话号码并不重要。该方法返回BOOL,因此请检查是否为YES或NO


这应该可以回答是否有任何能够拨打电话的应用程序。因此,在未来的设备细分变化中,这应该是可以接受的。

我认为通常情况下是这样的。我会使用更通用的字符串比较(只是为了在将来更新时更安全)。我使用它没有任何问题(到目前为止…)


如果您想更确定设备是否能够实际进行调用,还应该利用核心电话API。CTCarrier类可以告诉您是否可以在任何特定时刻拨打电话。

简单地检查设备是否“支持”电话可能不是最好的方式,这取决于您试图完成的任务。信不信由你,有些人在没有服务的情况下使用旧iphone,就像使用ipodtouch一样。有时人们的iPhone中没有安装SIM卡。在我的应用程序中,如果用户设备能够拨号,我想拨一个电话号码,否则我想显示电话号码并提示用户抓取一个电话并拨号。这是我提出的一个迄今为止行之有效的解决方案。请随意评论和改进它

// You must add the CoreTelephony.framework
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>

-(bool)canDevicePlaceAPhoneCall {
    /*

     Returns YES if the device can place a phone call

     */

    // Check if the device can place a phone call
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]]) {
        // Device supports phone calls, lets confirm it can place one right now
        CTTelephonyNetworkInfo *netInfo = [[[CTTelephonyNetworkInfo alloc] init] autorelease];
        CTCarrier *carrier = [netInfo subscriberCellularProvider];
        NSString *mnc = [carrier mobileNetworkCode]; 
        if (([mnc length] == 0) || ([mnc isEqualToString:@"65535"])) {
            // Device cannot place a call at this time.  SIM might be removed.
            return NO;
        } else {
            // Device can place a phone call
            return YES;
        }
    } else {
        // Device does not support phone calls
        return  NO;
    }
}
//您必须添加coretephony.framework
#进口
#进口
-(bool)CandevicePlacePhoneCall{
/*
如果设备可以拨打电话,则返回YES
*/
//检查设备是否可以拨打电话
if([[UIApplication sharedApplication]canOpenURL:[NSURL URLWithString:@“tel:/”])){
//该设备支持电话,让我们确认它可以立即拨打电话
CTTelephonyNetworkInfo*netInfo=[[CTTelephonyNetworkInfo alloc]init]autorelease];
CTCarrier*carrier=[netInfo subscriberCellularProvider];
NSString*mnc=[carrier mobileNetworkCode];
如果([mnc长度]==0)| |([mnc isEqualToString:@“65535”])){
//设备此时无法拨打电话。SIM卡可能已被删除。
返回否;
}否则{
//该设备可以拨打电话
返回YES;
}
}否则{
//设备不支持电话呼叫
返回否;
}
}

你会注意到我检查mobileNetworkCode是否为65535。在我的测试中,当您取出SIM卡时,mobileNetworkCode似乎设置为65535。无法100%确定原因。

我需要确保来电不会中断我的客户录制的录音,因此我会提示他们进入飞行模式,但仍然打开wifi。Albebe的上述方法在iOS 8.1.3上对我不起作用,但如果我发现这个解决方案应该在iOS 7及更高版本中起作用:

您必须添加并导入corethelphony.framework

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
初始化
CTTelephonyNetworkInfo

self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];
然后,当它发生变化时,您将收到回调:

- (void)radioAccessChanged {
    NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);
}
currentRadioAccessTechnology
的值在中定义 CTTelephonyNetworkInfo.h,当没有基站连接时,您将返回null/nil


这就是我发现它的地方:

根据@the guardian的回复,我提出了以下(swift):


这段代码已经在iPadAir 2 Wifi、iPadAir 2模拟器和iPhone6sPlus上进行了测试,似乎工作正常。将很快在带有移动数据的iPad上确定

根据@TheGuardian的回答,我认为这可能是一个更简单的方法:

   private final func canMakePhoneCall() -> Bool {
       guard UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Phone else {
        return false
       }

       let mobileNetworkCode = CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode
       let isInvalidNetworkCode = mobileNetworkCode == nil || mobileNetworkCode?.characters.count <= 0
                                                        || mobileNetworkCode == "65535"
                                                        //When sim card is removed, the Code is 65535

       return !isInvalidNetworkCode
    }
private final func canMakePhoneCall()->Bool{
guard UIDevice.currentDevice().userInterfaceIdiom==UIUserInterfaceIdiom.Phone else{
返回错误
}
让mobileNetworkCode=CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode

让isInvalidNetworkCode=mobileNetworkCode==nil | | mobileNetworkCode?.characters.countThis
UIApplication.shared.openURL((URL(字符串:“电话:/\(电话号码)”)!)
不会说它是否有SIM卡,这只会说,设备是否有拨打电话的选项。例如:有SIM卡或没有SIM卡的iPhone将返回true,但在iPod Touch中它将始终返回false,就像wise如果ipad没有SIM卡选项,它将返回false一样

以下是全面检查所有内容的代码!(使用Swift 3.0)


通过这种方式,我们可以确保设备支持或不支持呼叫。

以防您要求拨打电话号码并显示 没有电话的设备上出现错误:

void openURL(NSURL *url, void (^ __nullable completionHandler). (BOOL success))
{
    if (@available(iOS 10.0, *)) {
        [application openURL:url options:@{} completionHandler:^(BOOL success) {
            completionHandler(success);
        }];
    } else
    {
        if([application openURL:url]) {
            completionHandler(YES);
        } else {
            completionHandler(NO);
        }
    }
}
用法


我想指出的是,这种方法可能会让人们忽略一些东西。如果设备处于飞行模式,或者SIM卡被移除,或者SIM卡服务被停用,那么“技术上”设备支持电话呼叫,但这并不意味着它“可以”现在就打电话。尽管听起来很少见,但人们使用旧iPhone而不提供iPod Touch服务。这需要根据你的努力来考虑。完全同意阿尔比的观点
import CoreTelephony

/**
 Indicates if the device can make a phone call.

 - seealso: [Source](http://stackoverflow.com/a/11595365/3643020)

 - returns: `true` if the device can make a phone call. `false` if not.
 */
final class func canMakePhoneCall() -> Bool {
    guard let url = URL(string: "tel://") else {
        return false
    }

    let mobileNetworkCode = CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode

    let isInvalidNetworkCode = mobileNetworkCode == nil
        || mobileNetworkCode?.count == 0
        || mobileNetworkCode == "65535"

    return UIApplication.shared.canOpenURL(url)
        && !isInvalidNetworkCode
}
   private final func canMakePhoneCall() -> Bool {
       guard UIDevice.currentDevice().userInterfaceIdiom == UIUserInterfaceIdiom.Phone else {
        return false
       }

       let mobileNetworkCode = CTTelephonyNetworkInfo().subscriberCellularProvider?.mobileNetworkCode
       let isInvalidNetworkCode = mobileNetworkCode == nil || mobileNetworkCode?.characters.count <= 0
                                                        || mobileNetworkCode == "65535"
                                                        //When sim card is removed, the Code is 65535

       return !isInvalidNetworkCode
    }
if UIApplication.shared.canOpenURL(URL(string: "tel://\(phoneNumber)")!) {
            var networkInfo = CTTelephonyNetworkInfo()
            var carrier: CTCarrier? = networkInfo.subscriberCellularProvider
            var code: String? = carrier?.mobileNetworkCode
            if (code != nil) {
                UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!))
            }
            else {
                var alert = UIAlertView(title: "Alert", message: "No SIM Inserted", delegate: nil, cancelButtonTitle: "ok", otherButtonTitles: "")
                alert.show()
            }
        }
        else {
            var alert = UIAlertView(title: "Alert", message: "Device does not support phone calls.", delegate: nil, cancelButtonTitle: "ok", otherButtonTitles: "")
            alert.show()
        }
void openURL(NSURL *url, void (^ __nullable completionHandler). (BOOL success))
{
    if (@available(iOS 10.0, *)) {
        [application openURL:url options:@{} completionHandler:^(BOOL success) {
            completionHandler(success);
        }];
    } else
    {
        if([application openURL:url]) {
            completionHandler(YES);
        } else {
            completionHandler(NO);
        }
    }
}
        p97openURL(phoneURL, ^(BOOL success) {
            if(!success) {
                  show message saying there is no telephony on device

            }
        }