美文网首页
iOS指纹登录

iOS指纹登录

作者: JoyceZhao | 来源:发表于2020-06-24 16:51 被阅读0次
    • 功能需求

    用户首次登录APP后,开启指纹验证功能,当APP由后台进入前台或重启时,APP需要验证指纹,通过后才能正常使用APP,无需后端处理。

    • 使用场景
    1. 用户首次登录-》开启指纹验证-》APP进入后台-》APP再次进入前台-》验证用户指纹-》验证成功后,正常使用APP
    2. 用户首次登录-》开启指纹验证-》双击上滑删除处于后台的APP-》再次打开APP-》验证用户指纹-》验证成功后,正常使用APP
    • 涉及的知识点
    #import <LocalAuthentication/LocalAuthentication.h>
    LocalAuthentication 是苹果封装提供的实现生物信息(Face ID、Touch ID、 device passcode)识别的框架,无法获取用户的生物信息,只能使用已经录入到本机的用户的生物信息。
    
    
    // 检测设备是否支持生物信息识别
    - (BOOL)canEvaluatePolicy:(LAPolicy)policy error:(NSError * __autoreleasing *)error __attribute__((swift_error(none)))
        API_AVAILABLE(macos(10.10), ios(8.0), watchos(3.0), tvos(10.0));
    
    // 验证生物信息
    - (void)evaluatePolicy:(LAPolicy)policy
           localizedReason:(NSString *)localizedReason
                     reply:(void(^)(BOOL success, NSError * __nullable error))reply
        API_AVAILABLE(macos(10.10), ios(8.0), watchos(3.0), tvos(10.0));
    
    // LAPolicy
    LAPolicyDeviceOwnerAuthenticationWithBiometrics // Face ID or Touch ID
    LAPolicyDeviceOwnerAuthentication //  device passcode
    
    // 查看指纹数据,NSData类型,不透明不可见
    context.evaluatedPolicyDomainState
    
    // app进入后台执行的代理方法
    - (void)applicationDidEnterBackground:(UIApplication *)application
    
    // app进入前台执行的代理方法
    - (void)applicationWillEnterForeground:(UIApplication *)application
    
    // app重启时执行的代理方法
    - (void)applicationDidBecomeActive:(UIApplication *)application
    
    • 代码实现-关键代码
    // startAutoLoginState用于保存用户设置结果
    
    
    // MARK: 登录后指纹开启提示
    - (void) canEvaluatePolicyTip {
        
        // 初始化上下文对象
        LAContext *context = [[LAContext alloc] init];
        
        NSError *error = nil;
        
        // 判断设备是否支持指纹识别功能
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error])
        {
            // 支持指纹验证
            UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"登录成功!" message:@"是否启用指纹登录" preferredStyle:UIAlertControllerStyleAlert];
    
            WeakSelf(self)
    
            UIAlertAction *donotStartUseAction = [UIAlertAction actionWithTitle:@"暂不开启" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
    
                [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"startAutoLoginState"];
                
                [weakSelf.navigationController popViewControllerAnimated:YES];
    
            }];
    
            UIAlertAction *startUseAction = [UIAlertAction actionWithTitle:@"立即开启" style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
    
                [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"startAutoLoginState"];
    
                [weakSelf evaluatePolicyAuthentication];
                
                [weakSelf dismissViewControllerAnimated:YES completion:nil];
    
            }];
            [alertController addAction:donotStartUseAction];
            [alertController addAction:startUseAction];
            
            [self presentViewController:alertController animated:YES completion:nil];
            
            return;
        }
        else {
            // 不支持指纹验证
            [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"startAutoLoginState"];        
            [self dismissViewControllerAnimated:YES completion:nil];
        }
    }
    
    // MARK: 设置页面中设置指纹开启关闭状态
    - (IBAction)fingerSwitchClick:(UISwitch *)sender {
        
        // 初始化上下文对象
        LAContext *context = [[LAContext alloc] init];
        
        NSError *error = nil;
        
        // 判断设备是否支持指纹识别功能
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error])
        {
            // 支持指纹验证
            if (sender.on) {
                
                [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"startAutoLoginState"];
                
                [SVProgressHUD showSuccessWithStatus:@"开启成功"];
                [SVProgressHUD setFadeInAnimationDuration:0];
                [SVProgressHUD dismissWithDelay:2];
            } else {
                   
                   [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"startAutoLoginState"];
               }
            
            return;
        }
        else {
            [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"startAutoLoginState"];
            
            [SVProgressHUD showErrorWithStatus:@"设备不支持指纹或锁屏密码"];
            [SVProgressHUD setFadeInAnimationDuration:0];
            [SVProgressHUD dismissWithDelay:2];
        }
    }
    
    // MARK: 指纹登录验证
    - (void) evaluatePolicyAuthentication {
    
        WeakSelf(self)
    
        LAContext *context = [[LAContext alloc] init];
    
        NSError *authError = nil;
    
        NSString *myLocalizedReasonString = @"请按住Home键完成验证";
        
        // 判断设备是否支持指纹识别
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&authError])
        {
            [context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:myLocalizedReasonString reply:^(BOOL success, NSError * _Nullable error) {
                if(success)
                {
                    NSLog(@"%@",context.evaluatedPolicyDomainState);
                    NSLog(@"指纹认证成功");
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        // 处理验证成功后逻辑
                    }];
                }
                else
                {
                    switch (error.code)
                    {
                        case LAErrorAuthenticationFailed:
                        {
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                
                                [SVProgressHUD showErrorWithStatus:@"验证失败"];
                                [SVProgressHUD setFadeInAnimationDuration:0];
                                [SVProgressHUD dismissWithDelay:2];
                            }];
                        }
                            break;
                        case LAErrorSystemCancel:
                        {
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                
                                [SVProgressHUD showErrorWithStatus:@"系统取消输入验证信息"];
                                [SVProgressHUD setFadeInAnimationDuration:0];
                                [SVProgressHUD dismissWithDelay:2];
                            }];
                        }
                            break;
                        case LAErrorPasscodeNotSet:
                        {
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                
                                [SVProgressHUD showErrorWithStatus:@"设备系统未设置密码"];
                                [SVProgressHUD setFadeInAnimationDuration:0];
                                [SVProgressHUD dismissWithDelay:2];
                            }];
                        }
                            break;
                        case LAErrorUserCancel:
                        {
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                
                                [SVProgressHUD showErrorWithStatus:@"用户取消输入验证信息"];
                                [SVProgressHUD setFadeInAnimationDuration:0];
                                [SVProgressHUD dismissWithDelay:2];
                            }];
                        }
                            break;
                        case LAErrorUserFallback: 
                        {
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                
                                [SVProgressHUD showErrorWithStatus:@"验证被取消"];
                                [SVProgressHUD setFadeInAnimationDuration:0];
                                [SVProgressHUD dismissWithDelay:2];
                            }];
    
                        }
                            break;
    
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_9_0
                        case LAErrorBiometryLockout: 
                        {
                            [SVProgressHUD showErrorWithStatus:@"Touch ID被锁,需要用户输入密码解锁"];
                            [SVProgressHUD setFadeInAnimationDuration:0];
                            [SVProgressHUD dismissWithDelay:2];
                        }
                            break;
                        case LAErrorAppCancel: 
                        {
                            NSLog(@"用户不能控制情况下APP被挂起"); // -9
                        }
                            break;
                        case LAErrorInvalidContext: 
                        {
                            NSLog(@"LAContext传递给这个调用之前已经失效"); // -10
                        }
                            break;
    #else
    #endif
                        default:
                        {
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                NSLog(@"其他情况,切换主线程处理");
    
                                [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"startAutoLoginState"];
                            }];
                            break;
                        }
                    }
                }
            }];
        }
        else
        {
            NSLog(@"设备不支持验证信息");
            
            [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:NO] forKey:@"startAutoLoginState"];
            switch (authError.code)
            {
                case LAErrorBiometryNotEnrolled:
                {
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        
                        [SVProgressHUD showErrorWithStatus:@"设备系统未设置指纹"];
                        [SVProgressHUD setFadeInAnimationDuration:0];
                        [SVProgressHUD dismissWithDelay:2];
                    }];
                    break;
                }
                case LAErrorPasscodeNotSet:
                {
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        
                        [SVProgressHUD showErrorWithStatus:@"设备系统未设置密码"];
                        [SVProgressHUD setFadeInAnimationDuration:0];
                        [SVProgressHUD dismissWithDelay:2];
                    }];
                    break;
                }
                default:
                {
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        
                        [SVProgressHUD showErrorWithStatus:@"验证信息不可用"];
                        [SVProgressHUD setFadeInAnimationDuration:0];
                        [SVProgressHUD dismissWithDelay:2];
                    }];
                    break;
                }
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:iOS指纹登录

          本文链接:https://www.haomeiwen.com/subject/nzhrfktx.html