下面的代码可靠吗,用于确定设备是否支持电话呼叫?我的担忧是如果苹果将 iPhone 字符串更改为其他任何内容,比如"iPhone 3G"、"iPhone 4"等。
[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
下面的代码可靠吗,用于确定设备是否支持电话呼叫?我的担忧是如果苹果将 iPhone 字符串更改为其他任何内容,比如"iPhone 3G"、"iPhone 4"等。
[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
iPhone支持tel:// URI方案。因此,您可以使用:
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
canOpenURL: 明确检查是否有能够打开该URL方案的应用程序,而不是URL是否正确。因此,未指定任何电话号码并不重要。该方法返回一个BOOL值,因此请检查是否为YES或NO。
这应该确切地回答了是否存在能够进行电话呼叫的应用程序。因此,它应该对设备分割的任何未来更改都可以使用。
仅仅检查设备是否“支持”电话可能不是最好的方法,这取决于你想要实现的目标。信不信由你,有些人使用没有服务的旧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;
}
}
你可能会注意到我检查mobileNetworkCode是否为65535。在我的测试中,当你拿掉了SIM卡后,mobileNetworkCode就会被设置为65535。不确定为什么会这样。
FF
以指示该值未设置[1]https://standards.ieee.org/content/dam/ieee-standards/standards/web/documents/tutorials/bopid.pdf - alfwatt我需要确保客户录制时来电不会打断录音。因此,我提示他们进入飞行模式,但仍打开wifi。AlBeebe上述方法在iOS 8.1.3上对我无效,但我发现了这个解决方案,适用于iOS 7及更高版本:
您必须添加并导入CoreTelephony.framework。
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
如果您想跟踪更改,请在您的类上定义该属性。
@property (strong, nonatomic) CTTelephonyNetworkInfo* networkInfo;
初始化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。import CoreTelephony
/**
Indicates if the device can make a phone call.
- seealso: [Source](https://dev59.com/LW445IYBdhLWcg3wAFcC#11595365)
- 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
}
这段代码已经在iPad Air 2 Wifi、iPad Air 2模拟器和iPhone 6S Plus上进行过测试,看起来运行正常。很快将在具有移动数据的iPad上进行测试。
我认为通常是这样的。我会选择更通用的字符串比较(以防未来更新时更安全)。我已经使用它并且没有遇到任何问题(至少目前还没有...)。
如果你想更确定设备是否能够实际拨打电话,你还应该利用核心电信API。 CTCarrier类可以告诉您在任何特定时刻是否可以实际拨打电话。
这个UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!))
只会判断设备是否有拨打电话的选项,而不是判断设备是否有SIM卡。例如:无论iPhone是否插入SIM卡,它都会返回true,但iPod Touch则始终返回false,同样地,如果iPad没有SIM卡选项,它也会返回false。
以下是检查所有内容的代码!(使用Swift 3.0)
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
}
}
根据@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
}