reinicia - Determine si un dispositivo iOS admite TouchID sin configurar el código de acceso
touch id no reconoce mi huella (6)
Actualmente estoy desarrollando una aplicación iOS que permite a los usuarios iniciar sesión en la aplicación utilizando TouchID, pero primero deben configurar una contraseña dentro de la aplicación. El problema es que, para mostrar la opción de contraseña de configuración para habilitar el inicio de sesión de TouchID, necesito detectar si el dispositivo iOS es compatible con TouchID.
Al usar LAContext y canEvaluatePolicy (como las respuestas aquí, si el dispositivo es compatible con Touch ID ), puedo determinar si el dispositivo actual es compatible con TouchID si el usuario ha configurado el código de acceso en su dispositivo iOS . Aquí está un fragmento de mi código (estoy usando Xamarin, así que está en C #):
static bool DeviceSupportsTouchID ()
{
if (UIDevice.CurrentDevice.CheckSystemVersion(8, 0))
{
var context = new LAContext();
NSError authError;
bool touchIDSetOnDevice = context.CanEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, out authError);
return (touchIDSetOnDevice || (LAStatus) Convert.ToInt16(authError.Code) != LAStatus.TouchIDNotAvailable);
}
return false;
}
Si el usuario no ha configurado el código de acceso del dispositivo , authError simplemente devolverá el error " PasscodeNotSet ", independientemente de si el dispositivo es compatible con TouchID o no.
Si el dispositivo del usuario es compatible con TouchID, quiero mostrar siempre la opción TouchID en mi aplicación, independientemente de si el usuario ha configurado el código de acceso en su dispositivo (solo advertiré al usuario que primero configure el código de acceso en su dispositivo). Viceversa, si el dispositivo del usuario no es compatible con TouchID, obviamente no quiero mostrar la opción TouchID en mi aplicación.
Entonces, mi pregunta es, ¿existe una buena manera de determinar de manera consistente si un dispositivo iOS es compatible con TouchID, independientemente de si el usuario ha configurado el código de acceso en su dispositivo?
La única solución que se me ocurre es determinar la arquitectura del dispositivo (que se responde en Determinar si el dispositivo iOS es de 32 o 64 bits ), ya que TouchID solo se admite en dispositivos con arquitectura de 64 bits. Sin embargo, estoy buscando si hay alguna manera mejor de hacer esto.
¡Gracias de antemano! :)
En conclusión, a continuación, no se puede determinar si un dispositivo es compatible con TouchID o no cuando el usuario no ha configurado el código de acceso en su dispositivo.
He informado de este error TouchID en el reportero de errores de Apple. Aquellos que quieran seguir el problema pueden verlo en Open Radar aquí: http://www.openradar.me/20342024
Gracias @rckoenes por la entrada :)
EDITAR
Resulta que alguien ya ha reportado un problema similar (# 18364575). Aquí está la respuesta de Apple con respecto al tema:
"La ingeniería ha determinado que este problema se comporta según lo previsto en base a la siguiente información:
Si no se establece el código de acceso, no podrá detectar la presencia de Touch ID. Una vez que se establece el código de acceso, canEvaluatePolicy finalmente devolverá LAErrorTouchIDNotAvailable o LAErrorTouchIdNotEnrolled y podrá detectar la presencia / estado de Touch ID.
Si los usuarios han deshabilitado el código de acceso en el teléfono con Touch ID, sabían que no podrán usar Touch ID, por lo que las aplicaciones no necesitan detectar la presencia de Touch ID ni promover funciones basadas en Touch ID. "
Entonces ..... la respuesta final de Apple es No. :(
Nota: una pregunta similar de de la persona que reportó esto -> iOS8 verifica si el dispositivo tiene Touch ID (pregunto por qué no encontré esta pregunta antes a pesar de mi extensa búsqueda ...)
Esta es una forma un tanto tediosa de averiguar si el dispositivo tiene un sensor de identificación física.
+ (BOOL)isTouchIDExist {
if(![LAContext class]) //Since this mandotory class is not there, that means there is no physical touch id.
return false;
//Get the current device model name
size_t size;
sysctlbyname("hw.machine", NULL, &size, NULL, 0);
char *model = malloc(size);
sysctlbyname("hw.machine", model, &size, NULL, 0);
NSString *deviceModel = [NSString stringWithCString:model encoding:NSUTF8StringEncoding];
//Devices that does not support touch id
NSArray *deviceModelsWithoutTouchID = [[NSArray alloc]
initWithObjects:
@"iPhone1,1", //iPhone
@"iPhone1,2", //iPhone 3G
@"iPhone2,1", //iPhone 3GS
@"iPhone3,1", //iPhone 4
@"iPhone3,2",
@"iPhone3,3",
@"iPhone4,1", //iPhone 4S
@"iPhone5,1", //iPhone 5
@"iPhone5,2",
@"iPhone5,3", //iPhone 5C
@"iPhone5,4",
@"iPod1,1", //iPod
@"iPod2,1",
@"iPod3,1",
@"iPod4,1",
@"iPod5,1",
@"iPod7,1",
@"iPad1,1", //iPad
@"iPad2,1", //iPad 2
@"iPad2,2",
@"iPad2,3",
@"iPad2,4",// iPad mini 1G
@"iPad2,5",
@"iPad2,5",
@"iPad2,7",
@"iPad3,1", //iPad 3
@"iPad3,2",
@"iPad3,3",
@"iPad3,4", //iPad 4
@"iPad3,5",
@"iPad3,6",
@"iPad4,1", //iPad Air
@"iPad4,2",
@"iPad4,3",
@"iPad4,4", //iPad mini 2
@"iPad4,5",
@"iPad4,6",
@"iPad4,7",
nil];
return ![deviceModelsWithoutTouchID containsObject:deviceModel];
}
Referencia: https://www.theiphonewiki.com/wiki/Models https://en.wikipedia.org/wiki/IOS
La forma correcta de detectar si TouchID está disponible:
BOOL hasTouchID = NO;
// if the LAContext class is available
if ([LAContext class]) {
LAContext *context = [LAContext new];
NSError *error = nil;
hasTouchId = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
}
Disculpe, está en Objective-C, puede que tenga que traducirlo a C #.
Debe abstenerse de verificar la versión del sistema y simplemente verificar si la clase o los métodos están disponibles o no.
Para iOS 11+ puede usar biometryType: LABiometryType
de LAContext
. Más de la documentación de Apple:
/// Indicates the type of the biometry supported by the device.
///
/// @discussion This property is set only when canEvaluatePolicy succeeds for a biometric policy.
/// The default value is LABiometryTypeNone.
@available(iOS 11.0, *)
open var biometryType: LABiometryType { get }
@available(iOS 11.0, *)
public enum LABiometryType : Int {
/// The device does not support biometry.
@available(iOS 11.2, *)
case none
/// The device does not support biometry.
@available(iOS, introduced: 11.0, deprecated: 11.2, renamed: "LABiometryType.none")
public static var LABiometryNone: LABiometryType { get }
/// The device supports Touch ID.
case touchID
/// The device supports Face ID.
case faceID
}
Sé que esta es una pregunta del año pasado, pero esta solución no hace lo que necesita. (Código SWIFT)
if #available(iOS 8.0, *) {
var error: NSError?
let hasTouchID = LAContext().canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)
//Show the touch id option if the device has touch id hardware feature (even if the passcode is not set or touch id is not enrolled)
if(hasTouchID || (error?.code != LAError.TouchIDNotAvailable.rawValue)) {
touchIDContentView.hidden = false
}
}
Luego, cuando el usuario presiona el botón para iniciar sesión con la identificación táctil:
@IBAction func loginWithTouchId() {
let context = LAContext()
var error: NSError?
let reasonString = "Log in with Touch ID"
if (context.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &error)) {
[context.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: NSError?) -> Void in
//Has touch id. Treat the success boolean
})]
} else {
//Then, if the user has touch id but is not enrolled or the passcode is not set, show a alert message
switch error!.code{
case LAError.TouchIDNotEnrolled.rawValue:
//Show alert message to inform that touch id is not enrolled
break
case LAError.PasscodeNotSet.rawValue:
//Show alert message to inform that passcode is not set
break
default:
// The LAError.TouchIDNotAvailable case.
// Will not catch here, because if not available, the option will not visible
}
}
}
¡Espero eso ayude!
Para el objetivo c
Funciona muy bien en todos los dispositivos sin verificar la versión del dispositivo.
- (void)canAuthenticatedByTouchID{
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = touchIDRequestReason;
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
}else{
switch (authError.code) {
case kLAErrorTouchIDNotAvailable:
[labelNotSupportTouchID setHidden:NO];
[switchBtn setHidden:YES];
[labelEnableTouchid setHidden:YES];
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self showAlertMessage:@"EyeCheck Pro" message:@"Device does not support Touch ID Service."];
});
break;
}
}
}