以下代码是否可靠用于确定设备是否可以支持电话? 我担心的是,如果苹果将iphone字符串更改为其他任何内容,我们可以说他们决定使用“iphone 3g”,“iphone 4”等。
[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
答案 0 :(得分:97)
iPhone支持tel:// URI方案。所以你可以使用:
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
canOpenURL:显式检查是否有能够打开该URL方案的应用程序,而不是URL是否正确。所以没有指定电话号码也没关系。该方法返回BOOL,因此请检查是否为NO。
这应该从字面上回答是否存在能够拨打电话的任何应用程序。因此,对设备细分的任何未来变化都应该没有问题。
答案 1 :(得分: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;
}
}
您将注意到我检查了mobileNetworkCode是否为65535.在我的测试中,当您移除SIM卡时,似乎移动网络代码设置为65535.不是100%确定为什么会这样。
答案 2 :(得分:11)
我需要确保拨入的电话不会中断我的客户拨打的录音,因此我提示他们进入飞行模式但仍然打开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。
这是我找到的地方:http://www.raywenderlich.com/48001/easily-overlooked-new-features-ios-7
答案 3 :(得分:10)
基于@ the-guardian的回复,我提出了以下内容(快速):
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
}
此代码已经在iPad Air 2 Wifi,iPad Air 2模拟器,iPhone 6S Plus上进行了测试,似乎运行正常。很快就会在iPad上确定移动数据。
答案 4 :(得分:2)
我认为您的方法不可靠,因为设备名称将来可能会发生变化。如果您担心的是阻止该应用在非iPhone设备上运行,您可以将“电话”添加到Info.plist中的UIRequiredDeviceCapabilities字典中。这将禁止iPhone以外的设备从App Store下载您的应用程序。
或者,如果您需要在特定时刻检查3G连接,可以使用Apple的Reachability实用程序类询问当前的3G / WIFI连接状态。
答案 5 :(得分:2)
我认为通常是这样。我会寻求更通用的字符串比较(以便在将来更新时更安全)。我使用它没有问题(到目前为止......)。
如果您想更确定设备是否可以实际拨打电话,您还应该利用Core Telephony API。 CTCarrier课程可以告诉您是否可以在任何特定时刻实际拨打电话。
答案 6 :(得分:2)
这个UIApplication.shared.openURL((URL(string: "tel://\(phoneNumber)")!))
不会说它是否有SIM卡,如果设备有拨打电话的选项,这就是说。 例如:有或没有SIM卡的iPhone会返回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()
}
通过这种方式,我们可以确定,设备支持是否支持。
答案 7 :(得分: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);
}
}
}
使用
p97openURL(phoneURL, ^(BOOL success) {
if(!success) {
show message saying there is no telephony on device
}
}
答案 8 :(得分:-1)
基于@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
}