ios - que - como hacer llamadas desde un ipad con sim
¿Detectando si el dispositivo soporta o no llamadas telefónicas? (9)
Basándome en la respuesta de @ TheGuardian, creo que este podría ser un enfoque más simple:
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
}
¿Es confiable el código a continuación para ser usado para determinar si un dispositivo puede soportar llamadas telefónicas o no? Mi preocupación es si Apple cambia la cadena del iphone a cualquier otra cosa, digamos que deciden tener "iphone 3g", "iphone 4", etc.
[[UIDevice currentDevice].model isEqualToString:@"iPhone"]
Basado en la respuesta de @ the-guardian, se me ocurrió lo siguiente (de manera rápida):
import CoreTelephony
/**
Indicates if the device can make a phone call.
- seealso: [Source](http://.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
}
Este código ha sido probado en un iPad Air 2 Wifi, un iPad Air 2 Simulator, un iPhone 6S Plus y parece funcionar correctamente. Se determinará en un iPad con datos móviles pronto.
Creo que en general lo es. Me gustaría una comparación de cadenas más genérica (solo para estar más segura en caso de una futura actualización). Lo he usado sin problemas (hasta ahora ...).
Si desea estar más seguro de si el dispositivo puede realizar llamadas, también debe aprovechar la API de telefonía principal. La clase CTCarrier puede decirle si puede hacer una llamada en cualquier momento.
Debo asegurarme de que las llamadas telefónicas entrantes no puedan interrumpir las grabaciones que realizan mis clientes, por lo que les pido que vayan al modo avión pero que todavía enciendan el wifi. El método anterior de AlBeebe no me funcionó en iOS 8.1.3, pero si encontré esta solución que debería funcionar en iOS 7 y posteriores:
Debe agregar e importar el CoreTelephony.framework.
#import <CoreTelephony/CTTelephonyNetworkInfo.h>
#import <CoreTelephony/CTCarrier.h>
Defina la propiedad en su clase si desea hacer un seguimiento de los cambios
@property (strong, nonatomic) CTTelephonyNetworkInfo* networkInfo;
CTTelephonyNetworkInfo
el CTTelephonyNetworkInfo
:
self.networkInfo = [[CTTelephonyNetworkInfo alloc] init];
NSLog(@"Initial cell connection: %@", self.networkInfo.currentRadioAccessTechnology);
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(radioAccessChanged) name:CTRadioAccessTechnologyDidChangeNotification object:nil];
Y luego recibirás una devolución de llamada cuando cambie:
- (void)radioAccessChanged {
NSLog(@"Now you''re connected via %@", self.networkInfo.currentRadioAccessTechnology);
}
Los valores de currentRadioAccessTechnology
se definen en CTTelephonyNetworkInfo.h y obtendrá un valor nulo / nulo cuando no haya una conexión de torre de celda.
Aquí es donde lo encontré: http://www.raywenderlich.com/48001/easily-overlooked-new-features-ios-7
El iPhone soporta el esquema tel: // URI. Para que puedas usar:
[[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:@"tel://"]];
canOpenURL: comprueba explícitamente si hay una aplicación capaz de abrir ese esquema de URL, no que la URL sea correcta. Así que no importa que no se especifique ningún número de teléfono. El método devuelve un BOOL, así que verifique que para SI o NO.
Eso debería responder literalmente si hay alguna aplicación presente capaz de hacer una llamada telefónica. Por lo tanto, debería estar bien contra cualquier cambio futuro en la segmentación de dispositivos.
El simple hecho de verificar si un dispositivo "admite" las llamadas telefónicas puede no ser la mejor manera de hacer las cosas, dependiendo de lo que esté intentando lograr. Lo creas o no, algunas personas usan iPhones viejos sin servicio como si fueran un iPod Touch. A veces las personas no tienen tarjetas SIM instaladas en sus iPhones. En mi aplicación, quería marcar un número de teléfono si el dispositivo de los usuarios podía, de lo contrario quería mostrar el número de teléfono y pedirle al usuario que agarre un teléfono y lo marque. Aquí hay una solución que se me ha ocurrido que ha funcionado hasta ahora. Siéntete libre de comentar y mejorarlo.
// 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;
}
}
Notará que verifico si el código de red móvil es 65535. En mis pruebas, parece que cuando retira la tarjeta SIM, el código de red móvil se establece en 65535. No estoy 100% seguro de por qué.
En caso de que solicite llamar a un número de teléfono y mostrar un error en dispositivos que no tienen telefonía:
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);
}
}
}
uso
p97openURL(phoneURL, ^(BOOL success) {
if(!success) {
show message saying there is no telephony on device
}
}
Esta UIApplication.shared.openURL((URL(string: "tel:///(phoneNumber)")!))
No dirá si tiene SIM o No, solo dirá si el dispositivo tiene opciones para realizar una llamada. Por ejemplo : un iPhone con o sin SIM devolverá verdadero, pero en el iPod Touch siempre devolverá falso, como si un ipad no tiene la opción de sim, devolverá falso.
¡Aquí está el código que comprueba todo de manera integral! (Utilizando 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()
}
De esta manera, podemos asegurarnos de que el dispositivo admite llamadas o no.
No creo que su método sea confiable, ya que los nombres de los dispositivos pueden cambiar en el futuro. Si su preocupación es evitar que la aplicación se ejecute en dispositivos que no sean iPhone, puede agregar la ''telefonía'' al diccionario de UIRequiredDeviceCapabilities en su lista de información. Eso no permitirá que otros dispositivos que no sean el iPhone descarguen su aplicación desde la App Store.
Alternativamente, si lo que necesita es verificar la conectividad 3G en un momento particular, puede usar la clase de utilidad de Reachability de Apple para preguntar sobre el estado actual de la conexión 3G / WIFI.