LAContext具有检查设备是否可以评估触摸ID并提供错误消息的方法。 问题是系统在两种情况下给出了相同的错误消息“LAErrorPasscodeNotSet”:
1)如果用户具有Touch ID,但在设置(iPhone 5s with iOS8)中将其关闭
2)如果设备没有Touch ID(带iOS8的iPad)
问:如何检查设备是否支持Touch ID,但是没有在设置中打开它?
更新
已经为Apple创建了关于此错误的门票(ID#18364575)并收到了答案:
“ Engineering已根据以下信息确定此问题的行为符合预期:
如果未设置密码,您将无法检测Touch ID的存在。设置密码后,canEvaluatePolicy将最终返回LAErrorTouchIDNotAvailable或LAErrorTouchIdNotEnrolled,您将能够检测到Touch ID状态/状态。
如果用户在具有Touch ID的手机上禁用了密码,他们就知道他们将无法使用Touch ID,因此这些应用无需检测Touch ID状态或推广基于Touch ID的功能。 “
答案 0 :(得分:7)
也许您可以编写自己的方法来检查您正在运行的设备,因为如果返回的错误相同,则很难确定是否支持Touch ID。我会选择这样的东西:
int sysctlbyname(const char *, void *, size_t *, void *, size_t);
- (NSString *)getSysInfoByName:(char *)typeSpecifier
{
size_t size;
sysctlbyname(typeSpecifier, NULL, &size, NULL, 0);
char *answer = malloc(size);
sysctlbyname(typeSpecifier, answer, &size, NULL, 0);
NSString *results = [NSString stringWithCString:answer encoding: NSUTF8StringEncoding];
free(answer);
return results;
}
- (NSString *)modelIdentifier
{
return [self getSysInfoByName:"hw.machine"];
}
获得模型标识符后,我只会检查模型标识符是否等于支持Touch ID的模型之一:
- (BOOL)hasTouchID
{
NSArray *touchIDModels = @[ @"iPhone6,1", @"iPhone6,2", @"iPhone7,1", @"iPhone7,2", @"iPad5,3", @"iPad5,4", @"iPad4,7", @"iPad4,8", @"iPad4,9" ];
NSString *model = [self modelIdentifier];
return [touchIDModels containsObject:model];
}
该数组包含支持Touch ID的所有型号ID,它们是:
此方法的唯一缺点是,一旦使用Touch ID发布新设备,模型阵列将不得不手动更新。
答案 1 :(得分:1)
在Swift 3中
fileprivate func deviceSupportsTouchId(success: @escaping () -> (), failure: @escaping (NSError) -> ()) {
let context = LAContext()
var authError: NSError?
let touchIdSetOnDevice = context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &authError)
if touchIdSetOnDevice {
DispatchQueue.main.async {
success()
}
}
else {
DispatchQueue.main.async {
failure(error!)
}
}
}
如果设备具有触摸Id功能,deviceSupportsTouchId()将返回Success。
如果没有,那么函数将返回错误,如果尚未设置touchIDNotEnrolled,则会给出以下错误代码。
LAError.Code.touchIDNotEnrolled.rawValue
您可以使用此值处理它。
答案 2 :(得分:1)
在这里你可以检查Touch-ID和Face-ID(使用iOS 11 +)
使用biometryType
的属性LAContext
来检查和评估可用的生物识别政策。 (对于密码验证,当生物识别失败时,请使用:LAPolicyDeviceOwnerAuthentication
)
试试这个,看看:
<强>目标-C:强>
LAContext *laContext = [[LAContext alloc] init];
NSError *error;
// For a passcode authentication , when biometric fails, use: LAPolicyDeviceOwnerAuthentication
//if ([laContext canEvaluatePolicy: LAPolicyDeviceOwnerAuthentication error:&error]) {
if ([laContext canEvaluatePolicy: LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error]) {
if (error != NULL) {
// handle error
} else {
if (@available(iOS 11, *)) {
if (laContext.biometryType == LABiometryTypeFaceID) {
//localizedReason = "Unlock using Face ID"
NSLog(@"FaceId support");
} else if (laContext.biometryType == LABiometryTypeTouchID) {
//localizedReason = "Unlock using Touch ID"
NSLog(@"TouchId support");
} else {
//localizedReason = "Unlock using Application Passcode"
NSLog(@"No biometric support or Denied biometric support");
}
} else {
// Fallback on earlier versions
}
[laContext evaluatePolicy: LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"Test Reason" reply:^(BOOL success, NSError * _Nullable error) {
if (error != NULL) {
// handle error
} else if (success) {
// handle success response
} else {
// handle false response
}
}];
}
}
<强>夫特:强>
let laContext = LAContext()
var error: NSError?
let biometricsPolicy = LAPolicy.deviceOwnerAuthentication //LAPolicy.deviceOwnerAuthenticationWithBiometrics
if laContext.isCredentialSet(LACredentialType.applicationPassword) {
print("Passsword is set")
}
let localizedFallbackTitle = "Unlock Using Device Passcode"
let localizedCancelTitle = "Use Application Passcode"
if (laContext.canEvaluatePolicy(biometricsPolicy, error: &error)) {
if let laError = error {
print("laError - \(laError)")
return
}
//print("biometricsPolicy - \(biometricsPolicy.rawValue)")
UINavigationBar.appearance().tintColor = UIColor.red
var localizedReason = "My Reason to be displayed on face id prompt"
if #available(iOS 11.0, *) {
if (laContext.biometryType == LABiometryType.faceID) {
//localizedReason = "Unlock using Face ID"
print("FaceId support")
} else if (laContext.biometryType == LABiometryType.touchID) {
//localizedReason = "Unlock using Touch ID"
print("TouchId support")
} else {
//localizedReason = "Unlock using Application Passcode"
print("No Biometric support")
}
} else {
// Fallback on earlier versions
}
laContext.localizedFallbackTitle = localizedFallbackTitle
laContext.localizedCancelTitle = localizedCancelTitle
//laContext.localizedReason = "test loc reason"
laContext.evaluatePolicy(biometricsPolicy, localizedReason: localizedReason, reply: { (isSuccess, error) in
DispatchQueue.main.async(execute: {
if let laError = error {
print("laError - \(laError)")
} else {
if isSuccess {
print("sucess")
} else {
print("failure")
}
}
})
})
}
答案 3 :(得分:0)
整合Touch ID
现在我们进入教程的主要部分......将Touch ID与应用程序集成。事实证明,Apple已经为访问Touch ID制作了一些相当标准的代码。代码来自本地身份验证框架,如下所示:
LAContext *myContext = [[LAContext alloc] init];
NSError *authError = nil;
NSString *myLocalizedReasonString = @"Used for quick and secure access to the test app";
if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {[myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
localizedReason:myLocalizedReasonString
reply:^(BOOL success, NSError *error) {
if (success) {
// User authenticated successfully, take appropriate action
}
else {
// User did not authenticate successfully, look at error and take appropriate action
}
}];
}
else {
// Could not evaluate policy; look at authError and present an appropriate message to user }
让我们看看每一行,看看它的作用:
第1行:这里我们创建一个LAContext对象。 LAContext类负责处理身份验证的上下文。简而言之,我们使用LAContext对象来检查是否有可用的身份验证类型。在本教程的情况下,我们稍后将检查“是否”触摸ID是一个选项。
第2行:我们需要一个NSError,以便LAContext可以在出现错误时使用它返回。
第3行:我们设置了一个NSString,其中包含一个放在屏幕上的描述,让用户知道触摸ID视图出现在屏幕上的原因。
第5行:这是我们通过调用canEvaluatePolicy:方法并将LAPolicy常量作为参数发送它来使用LAContext常量的地方。在这种情况下,我们传递LAPolicyDeviceOwnerAuthenticationWithBiometrics。如果此操作失败,则说明兼容设备上未配置触摸ID,或者设备上没有触摸ID ...请考虑运行该应用程序的iPhone 4S,5或5c。此外,这不会考虑运行iOS 7的设备,因此如果您计划在应用程序上运行指纹身份验证,请确保检查您是否正在使用兼容设备,如果没有,请提供其他选项,例如作为密码访问应用程序的密码。
第6,7和8行:如果用户可以使用生物识别进行身份验证,我们现在可以在LAContext对象上调用evaluatePolicy方法。我们通过传递相同的常量,LAPolicyDeviceOwnerAuthenticationWithBiometrics,以及传递我们的原因字符串,然后指定要处理的响应的块来完成此操作。
结果我们会得到YES或NO。如果是,那么第10行是我们放置代码以获得肯定响应的地方。同样,第12行是我们放置失败代码的地方。
最后在第15行,我们有ELSE语句,如果第5行未通过测试则运行...即,生物识别不可用。我们可以检查authError指针以获取原因并在需要时将其呈现给用户。
最后,为了使这不显示错误,我们需要将本地身份验证框架导入到我们的项目中:
因此,我们将此代码添加到我们的项目中。打开ViewController.m并在顶部导入本地身份验证框架。
有关详细信息,请访问此链接:http://www.devfright.com/touch-id-tutorial-objective-c/
答案 4 :(得分:0)
通过检查如下所示的错误代码,可以确定设备是否支持生物特征扫描(touchID和faceID):
func deviceSupportsBiometricScanning() -> Bool {
var authError: NSError?
let _ = LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError)
return authError?.code != kLAErrorBiometryNotAvailable.hashValue
}