17

LAContext 具有检查设备是否可以评估触摸 ID 并给出错误消息的方法。问题是系统在两种情况下给出了相同的错误消息“LAErrorPasscodeNotSet”:

1) 如果用户有 Touch ID,但在设置中将其关闭(iPhone 5s 和 iOS8)

2) 如果设备没有 Touch ID (iPad with iOS8)

Q:如何查看设备是否支持Touch ID,但在设置中没有开启?

更新:

已就此错误 (ID# 18364575) 向 Apple 创建了票证并收到了答复:

"工程部门根据以下信息确定此问题的行为符合预期:

如果未设置密码,您将无法检测到 Touch ID 的存在。设置密码后,canEvaluatePolicy 最终将返回 LAErrorTouchIDNotAvailable 或 LAErrorTouchIdNotEnrolled,您将能够检测到 Touch ID 的存在/状态。

如果用户在带有 Touch ID 的手机上禁用了密码,他们知道他们将无法使用 Touch ID,因此应用程序不需要检测 Touch ID 的存在或推广基于 Touch ID 的功能。"

4

5 回答 5

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"];
}

获得模型标识符后,我将检查模型标识符 equals 是否是支持 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,它们是:

  • iPhone 5S
  • iPhone 6
  • iPhone 6+
  • iPad 空气 2
  • iPad 迷你 3

这种方法的唯一缺点是,一旦发布了带有 Touch ID 的新设备,就必须手动更新模型数组。

于 2014-09-24T21:30:31.503 回答
1

在斯威夫特 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!)
        }
    }
}

deviceSupportsTouchId() 如果设备具有触摸 ID 功能,则返回成功。

如果没有,则函数将返回错误,如果 touchIDNotEnrolled 尚未设置,则会为您提供以下错误代码。

LAError.Code.touchIDNotEnrolled.rawValue

您可以使用此值处理它。

于 2017-02-02T20:37:49.757 回答
1

在这里您可以检查 Touch-ID 和 Face-ID(使用 iOS 11+)

使用 的属性biometryTypeLAContext检查和评估可用的生物识别策略。(对于密码认证,当生物识别失败时,使用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")
                }
            }

        })
    })
}
于 2018-01-23T09:58:45.510 回答
0

集成触控 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 行:这是我们使用 LAContext 常量的地方,方法是调用 canEvaluatePolicy: 方法并将 LAPolicy 常量作为参数发送给它。在这种情况下,我们通过 LAPolicyDeviceOwnerAuthenticationWithBiometrics。如果此操作失败,则可能是兼容设备上未配置触摸 ID,或者设备上没有触摸 ID……想想运行该应用程序的 iPhone 4S、5 或 5c。此外,这并没有考虑到运行 iOS 7 的设备,因此如果您计划在应用程序上运行指纹身份验证,请确保检查您使用的是兼容设备,如果不是,请提供其他选项,例如作为密码访问应用程序的密码。

第 6、7 和 8 行:如果用户可以使用生物特征进行身份验证,我们现在可以在 LAContext 对象上调用 evaluatePolicy 方法。我们通过传递相同的常量 LAPolicyDeviceOwnerAuthenticationWithBiometrics 以及传递我们的原因字符串然后为要处理的响应指定一个块来做到这一点。

我们将得到一个是或否的结果。如果是,那么第 10 行是我们放置积极响应代码的地方。同样,第 12 行是我们放置失败代码的地方。

最后在第 15 行,如果第 5 行未通过测试,我们将运行 ELSE 语句……即,生物特征不可用。我们可以检查 authError 指针以获取原因并在需要时将其呈现给用户。

最后,为了不显示错误,我们需要将本地身份验证框架导入到我们的项目中:

因此,让我们将此代码添加到我们的项目中。打开 ViewController.m 并在顶部导入本地身份验证框架。

有关更多详细信息,请访问此链接: http: //www.devfright.com/touch-id-tutorial-objective-c/

于 2015-08-18T05:05:28.110 回答
0

您可以通过检查错误代码来了解设备是否支持生物识别扫描(touchID 和 faceID),如下所示:

func deviceSupportsBiometricScanning() -> Bool {
    var authError: NSError?
    let _ = LAContext().canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &authError)
    return authError?.code != kLAErrorBiometryNotAvailable.hashValue
}
于 2018-11-02T05:43:07.270 回答