TouchID转到系统密码验证

14

我想使用TouchID来认证我的应用程序。

1.我希望用户可以点击“输入密码”以调用系统内置的密码屏幕进行身份验证,如果成功,则进入我的应用程序。
但是我不知道如何前往密码验证页面,就像'case LAErrorUserFallback'中显示的屏幕一样。 enter image description here

这是我的代码:

LAContext *context = [[LAContext alloc] init];
__block  NSString *msg;
__block  BOOL bAuth;
// show the authentication UI with our reason string
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"Unlock APP With FingerPrint", nil) reply:
^(BOOL success, NSError *authenticationError) {

   if (success) {
      bAuth = YES;
      msg =[NSString stringWithFormat:NSLocalizedString(@"EVALUATE_POLICY_SUCCESS", nil)];
      dispatch_async(dispatch_get_main_queue(), ^{
         [[MYAppDelegate theDelegate] initializeAppAfterKeyVaultUnlocked];
      });
      NSLog(@"%@",msg);
   } else {
      bAuth = NO;
      switch (authenticationError.code) {
         case LAErrorAuthenticationFailed:
            msg = [NSString stringWithFormat:NSLocalizedString(@"Authentication Failed", nil)];
            // ...
            break;

         case LAErrorUserCancel:
            msg = [NSString stringWithFormat:NSLocalizedString(@"User pressed Cancel button", nil)];
            dispatch_async(dispatch_get_main_queue(), ^{
               [[MYAppDelegate theDelegate] exitAndLock];
            });

            break;

         case LAErrorUserFallback:
            msg = [NSString stringWithFormat:NSLocalizedString(@"User pressed \"Enter Password\"", nil)];
            //Here I want to fallback to iOS build-in passcode authenticate view, and get the auth result.
            break;

         default:
            msg = [NSString stringWithFormat:NSLocalizedString(@"Touch ID is not configured", nil)];
            // ...
            break;
      }
      NSLog(@"%@",authenticationError.localizedDescription);

   }


}];
6个回答

13
现在在iOS 9中,实际上非常简单 - 您只需使用LAPolicyDeviceOwnerAuthentication替换LAPolicyDeviceOwnerAuthenticationWithBiometrics即可。
因此,在您的代码中,只需将此内容替换为:
[context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:NSLocalizedString(@"Unlock APP With FingerPrint", nil) reply:
^(BOOL success, NSError *authenticationError) {

使用此功能:

[context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:NSLocalizedString(@"Unlock APP With FingerPrint", nil) reply:
^(BOOL success, NSError *authenticationError) {
因此,当用户使用指纹认证失败时,将会出现“输入密码”的选项,该选项会调用系统密码输入界面。

这是正确的 - 只需使用 [context evaluatePolicy: LAPolicyDeviceOwnerAuthentication ..... (不带 WithBiometrics). - Paulo
我想要导航到自定义屏幕而不是系统密码屏幕,应该如何实现? - Jayprakash Dubey
@JayprakashDubey,你无法在自己的视图中使用系统密码。不过,你可以为你的应用程序构建专门的密码解决方案。 - Dannie P

1

我没有尝试过这个方法,但这篇文章声称你可以按照这里的方式使用系统(仅适用于iOS 8或更高版本)。

或者(这是我所做的)你可以构建你自己的密码输入屏幕(以支持旧版iOS),我的控制器有一个密码输入视图,在用户选择使用密码时会暴露出来。此时,evaluatePolicy的回调将返回LAErrorUserFallback,这可能是打开你自定义密码屏幕的时机。

类似这样:

-(void)maybeShowTouchIDMessage {
  if (![SettingsManager sharedManager].isUseTouchID || self.createPassCodeMode) {
    self.shieldView.hidden = YES;
    return;
  }

  self.shieldView.hidden = NO;
  self.shieldView.alpha = 1.0;

  LAContext *context = [[LAContext alloc] init];

  NSError *evalError = nil;
  if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&evalError] ) {
    __weak SecurityWindowViewController *weakSelf = self;
    [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
            localizedReason:@"Use touch id \n or hit \"Cancel\" to enter passcode"
                      reply:^(BOOL success, NSError *error) {
                        dispatch_async(dispatch_get_main_queue(), ^{
                          SecurityWindowViewController *strongSelf = weakSelf;
                          if (success) {
                            [strongSelf hideWithSuccess:YES];
                          } else if (error){
                            NSString *errorMessage;
                            BOOL showError = NO;
                            switch (error.code) {
                              case LAErrorAuthenticationFailed:
                                errorMessage = @"Sorry couldn't autheticate";
                                showError = YES;
                                break;
                              case LAErrorPasscodeNotSet:
                                errorMessage = @"Sorry couldn't autheticate";
                                showError = YES;
                                break;
                              case LAErrorTouchIDNotEnrolled:
                                errorMessage = @"Touch ID has no enrolled fingers";
                                showError = YES;
                                break;
                              default:
                                showError = NO;
                                break;
                            }
                            [UIView animateWithDuration:0.5 animations:^{
                              strongSelf.shieldView.alpha = 0.0;
                            } completion:^(BOOL finished) {
                              strongSelf.shieldView.hidden = YES;
                            }];
                            if (showError) {
                              UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error"
                                                                              message:errorMessage
                                                                             delegate:nil
                                                                    cancelButtonTitle:@"Ok"
                                                                    otherButtonTitles:nil];
                              [alert show];

                            }
                          }
                        });
                      }];

  } 

1
针对您的情况:
case LAErrorUserFallback:
      [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:NSLocalizedString(@"Unlock APP With PassCode", nil) reply: ^(BOOL success, NSError *authenticationError) {
  if(success){
    NSLog(@"PassCode Login successful");
  }else{
    NSLog(@"%@",authenticationError);
   }

}

为了进行设备密码验证,您需要使用LAPolicyDeviceOwnerAuthentication而不是LAPolicyDeviceOwnerAuthenticationWithBiometrics。希望这可以帮到您!


1

0

LAPolicy 策略枚举值 deviceOwnerAuthenticationWithBiometrics 替换为 deviceOwnerAuthentication

注意:如果用户启用了生物识别(面容 ID 或触控 ID)身份验证,则设备将首先要求进行生物识别身份验证,如果用户选择回退身份验证,则只会显示 deviceOwnerAuthentication 密码屏幕。

尝试这个并查看(Swift 4):

func touchIDAuthentication() {
    let context = LAContext()
    var error:NSError?

    // edit line - deviceOwnerAuthentication
    guard context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &error) else {
        //showAlertViewIfNoBiometricSensorHasBeenDetected()
        return
    }

    // edit line - deviceOwnerAuthentication
    if context.canEvaluatePolicy(.deviceOwnerAuthentication, error: &errorPointer) {

        // edit line - deviceOwnerAuthentication
        context.evaluatePolicy(.deviceOwnerAuthentication, localizedReason: reason, reply: { (success, error) in
            if success {
                DispatchQueue.main.async {
                    print("Authentication was successful")
                }
            }else {
                DispatchQueue.main.async {
                    //self.displayErrorMessage(error: error as! LAError )
                    print("Authentication was error")
                }
            }
        })
    }else {
       // self.showAlertWith(title: "Error", message: (errorPointer?.localizedDescription)!)
    }
}

0

你可以添加另一个 case 并从那里调用你的密码屏幕。

这是我的代码:

    LAContext *myContext = [[LAContext alloc] init];
    NSError *authError = nil;
    NSString *myLocalizedReasonString = strMessage;
    objFlockr.pVerificationBlock = objResponse;
    if ([myContext canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&authError]) {
        if (!isShow) {

            myContext.localizedFallbackTitle = @"";
        }
        else
        {
           myContext.localizedFallbackTitle =  @"Set Up Passcode";
        }

        [myContext evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics
                  localizedReason:myLocalizedReasonString
                            reply:^(BOOL succes, NSError *error) {

                                if  (!AppDel.firstAttampt && succes && !isShow)
                                {
                                    if (objFlockr.pVerificationBlock)
                                        objFlockr.pVerificationBlock(1);
                                }
                                else if (succes) {
                                    if (objFlockr.pVerificationBlock)
                                        objFlockr.pVerificationBlock(0);
                                    NSLog(@"User authenticated");
                                } else {

                                    switch (error.code) {
                                        case LAErrorAuthenticationFailed:
                                            NSLog(@"Authentication Failed");
                                            if (objFlockr.pVerificationBlock)
                                                objFlockr.pVerificationBlock(1);

                                            break;

                                        case LAErrorUserCancel:
                                            NSLog(@"User pressed Cancel button");
                                            if (objFlockr.pVerificationBlock)
                                                objFlockr.pVerificationBlock(3);
                                            break;

                                        case LAErrorUserFallback:
                                            NSLog(@"User pressed \"Enter Password\"");
                                            if (objFlockr.pVerificationBlock)
                                                objFlockr.pVerificationBlock(4);
                                            break;

                                        default:
                                            [self showMessage:@"Touch ID is not configured" withTitle:@"Error"];
                                            if (objFlockr.pVerificationBlock)
                                                objFlockr.pVerificationBlock(2);
                                            NSLog(@"Touch ID is not configured");
                                            break;
                                    }

                                    NSLog(@"Authentication Fails");
                                }
                            }];
    } else {
        NSLog(@"Can not evaluate Touch ID");
        [self showMessage:@"Can not evaluate TouchID" withTitle:@"Error"];
    }

嗨,我在密码方面遇到了问题。我收到了“errSecItemNotFound”错误。所以我需要首先在钥匙链中添加项目吗?我正在按照此示例代码使用。https://developer.apple.com/library/ios/samplecode/KeychainTouchID/Introduction/Intro.html - Nikunj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接