iOS8检查设备是否具有Touch ID

时间:2014-09-24 21:10:02

标签: ios iphone ios8 touch-id face-id

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的功能。 “

5 个答案:

答案 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,它们是:

  • iPhone 5s
  • iPhone 6
  • iPhone 6 +
  • iPad Air 2
  • iPad Mini 3

此方法的唯一缺点是,一旦使用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
}