检测设备是否支持电话?

ary*_*axt 45 iphone cocoa-touch objective-c phone-call ios

以下代码是否可靠用于确定设备是否可以支持电话呼叫?我担心的是,如果苹果将iphone字符串更改为其他任何东西,我们可以说他们决定使用"iphone 3g","iphone 4"等.

[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
Run Code Online (Sandbox Code Playgroud)

Tom*_*mmy 98

iPhone支持tel:// URI方案.所以你可以使用:

[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
Run Code Online (Sandbox Code Playgroud)

canOpenURL:显式检查是否有能够打开该URL方案的应用程序,而不是URL是否正确.所以没有指定电话号码也没关系.该方法返回BOOL,因此检查是否为YES.

这应该从字面上回答是否存在能够拨打电话的任何应用程序.因此,对设备细分的任何未来变化都应该没问题.

  • 我想指出一些人可能会忽略这种方法.如果设备处于飞行模式,或SIM卡被移除,或SIM卡服务被停用,则"技术上"设备支持电话呼叫,但这并不意味着它"此刻"可以"拨打"电话.尽管听起来很罕见,但人们使用没有服务的旧款iPhone作为iPod Touch.根据你想要完成的事情来考虑一些事情. (20认同)
  • 这在运行iOS 8.1的iPad2上返回TRUE.但是,它在我的iPad2 8.1模拟器上返回FALSE(正确的行为).所以不幸的是它不起作用,重要的是...... (5认同)
  • 请注意,这在IOS8测试版中不起作用.但可能是贝塔的一个错误.如果没有,则需要CTTelephonyNetworkInfo检查. (3认同)
  • iOS8GM也不起作用,所以看起来不是beta版的bug. (3认同)

AlB*_*ebe 64

简单地检查一下设备是否"支持"电话可能不是最好的方法,取决于你想要完成的事情.信不信由你,有些人使用旧的iPhone没有服务,就像他们是iPod Touch一样.有时人们的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;
    }
}
Run Code Online (Sandbox Code Playgroud)

您会注意到我检查mobileNetworkCode是否为65535.在我的测试中,当您移除SIM卡时,似乎移动网络代码设置为65535.不是100%确定为什么会这样.

  • 这在iOS 8.1.3上对我不起作用,无论是否在飞行模式下,mnc总是等于"02".但我发现了一个适用于iOS 7及更高版本的解决方案,请参阅下面的答案. (2认同)

flo*_*uni 11

我需要确保来电不能中断我的客户所做的录音,所以我提示他们进入飞行模式,但仍然打开wifi.上面的方法来自AlBeebe在iOS 8.1.3上对我不起作用,但是如果发现这个解决方案应该适用于iOS 7及更高版本:

您必须添加并导入CoreTelephony.framework.

#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
Run Code Online (Sandbox Code Playgroud)

如果要跟踪更改,请在类上定义属性

@property (strong, nonatomic) CTTelephonyNetworkInfo* networkInfo;  
Run Code Online (Sandbox Code Playgroud)

初始化CTTelephonyNetworkInfo:

self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];
Run Code Online (Sandbox Code Playgroud)

然后,当它发生变化时你会收到回调:

- (void)radioAccessChanged {
    NSLog(@"Now you're connected via %@", self.networkInfo.currentRadioAccessTechnology);
}
Run Code Online (Sandbox Code Playgroud)

这些值currentRadioAccessTechnology在CTTelephonyNetworkInfo.h中定义,当没有单元塔连接时,您将返回null/nil.

这是我发现它的地方:http://www.raywenderlich.com/48001/easily-overlooked-new-features-ios-7


Cam*_*ped 10

根据@ the-guardian的回复,我提出了以下内容(在swift中):

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
}
Run Code Online (Sandbox Code Playgroud)

此代码已在iPad Air 2 Wifi,iPad Air 2模拟器,iPhone 6S Plus上进行了测试,似乎运行正常.很快就会在iPad上确定移动数据.