iOS指纹解锁TouchID

作者: my_杨哥 | 来源:发表于2017-07-11 16:06 被阅读540次

    指纹解锁的使用越来越普遍了,主要是使用方便,再用之前还是先了解一下如何使用吧。

    一、API介绍

    使用指纹功能,必须用到系统的库,指纹用到的库是LocalAuthentication.framework,所以接下来我介绍一下这个库里的所有文件的作用。
    我们打开这个LocalAuthentication.framework库,发现里面就4个.h文件

    - LAContext.h
    - LAError.h
    - LAPublicDefines.h
    - LocalAuthentication.h
    

    1、LocalAuthentication.h

    这个里面就两行引入头文件,很显然这是我们引入指纹库要调用的类,可以在文件中引入#import <LocalAuthentication/LocalAuthentication.h>

    2、LAPublicDefines.h

    这个里面就是定义了一些宏定义,很简单都能看懂。

    3、LAError.h

    这个类其实也不难,就是一个枚举的里面列出了所有可能出现的错误类型,每个错误的类型都有注释,我给翻译一下

     LAErrorAuthenticationFailed //连续三次指纹验证失败,可能指纹模糊或用错手指
     LAErrorUserCancel           //用户取消验证,点击了取消按钮
     LAErrorUserFallback         //用户取消验证,点击了输入密码按钮
     LAErrorSystemCancel         //系统取消授权,如其他APP切入
     LAErrorPasscodeNotSet       //指纹验证无法启动/失败,因为设备没有设置密码
     LAErrorTouchIDNotAvailable  //设备TouchID不可用,例如未打开
     LAErrorTouchIDNotEnrolled   //指纹验证无法启动,因为没有录入指纹(设置密码了)
     LAErrorTouchIDLockout       //设备TouchID被锁定,因为失败的次数太多了
     LAErrorAppCancel            //应用程序取消了身份验证,APP调用了-(void)invalidate方法使LAContext失效
     LAErrorInvalidContext       //实例化的LAContext对象失效,再次调用evaluation...方法则会弹出此错误信息
    

    4、LAContext.h

    这个类才是最重要的核心部分。


    首先看到的是一个枚举LAPolicy,里面就两个

    LAPolicyDeviceOwnerAuthenticationWithBiometrics(iOS8以上可用):这种代表的是只用指纹去验证。第一次指纹失败,会出现“输入密码”按钮,输入密码的标题及功能可以自定义;第三次指纹失败,弹窗消失;再次启动验证,还有两次机会,如果都失败了,指纹验证锁定,不再弹出验证窗。直至输入密码来解锁指纹(可以锁屏重新进来使用输入密码的方式解锁)。
    LAPolicyDeviceOwnerAuthentication(iOS9以上可用):这种代表的是可以用指纹或密码两种方式去验证,优先用指纹。第一次指纹失败,会出现“输入密码”按钮,输入密码的标题可以自定义,但是功能不能自定义了,而是必须输入系统密码(锁屏密码);第三次验证失败,弹窗消失,弹出输入系统密码的界面;如果连续五次指纹失败,则指纹锁定,此时只会弹出输入密码界面,直至输入密码成功解锁。

    两种验证方式的比较:
    相同点:都是连续五次验证失败就会锁定
    不同点:前者的输入密码功能可以自定义,后者输入密码功能是固定输入系统密码
    一般经常使用前者LAPolicyDeviceOwnerAuthenticationWithBiometrics


    接下来就是实例方法,创建实例对象:LAContext *context = [LAContext alloc] init];context来调用。

    /*
      这个方法用来检查当前设备是否可用touchID,返回一个BOOL值
      policy: 这个就是上面的枚举的两个验证方式,一般用前者
      error:  错误的类型可参考LAError.h里的类型
    */
    - (BOOL)canEvaluatePolicy:(LAPolicy)policy error:(NSError * __autoreleasing *)error __attribute__((swift_error(none)));
    
    /*
      这个方法是开始验证指纹的方法
      policy: 这个就是上面的枚举的两个验证方式,一般用前者
      localizedReason: 指纹验证框上面的提示信息,一般为“通过Home键验证已有手机指纹”(不能为空否则崩溃)
      reply: 一个block,返回指纹验证结果,成功:success为YES,失败:success为NO,同时返回错误类型的error,同样参考LAError.h里的类型
    */
    - (void)evaluatePolicy:(LAPolicy)policy
           localizedReason:(NSString *)localizedReason
                     reply:(void(^)(BOOL success, NSError * __nullable error))reply;
    
    //用来废止该实例对象context
    - (void)invalidate NS_AVAILABLE(10_11, 9_0);
    

    下面的两个枚举和三个方法一般用不到,这里就不做介绍了

    // 两个枚举
    LACredentialType
    LAAccessControlOperation
    
    // 三个方法
    - (BOOL)setCredential:(nullable NSData *)credential
                     type:(LACredentialType)type NS_AVAILABLE(10_11, 9_0) __WATCHOS_AVAILABLE(3.0) __TVOS_UNAVAILABLE;
    
    - (BOOL)isCredentialSet:(LACredentialType)type NS_AVAILABLE(10_11, 9_0) __WATCHOS_AVAILABLE(3.0) __TVOS_UNAVAILABLE;
    
    - (void)evaluateAccessControl:(SecAccessControlRef)accessControl
                        operation:(LAAccessControlOperation)operation
                  localizedReason:(NSString *)localizedReason
                            reply:(void(^)(BOOL success, NSError * __nullable error))reply
                            NS_AVAILABLE(10_11, 9_0) __WATCHOS_AVAILABLE(3.0) __TVOS_UNAVAILABLE;
    
    

    还有五个属性

    // 可以设置指纹弹框“输入密码”按钮的标题,如果不设置或设置为nil,则显示默认的“输入密码”;如果设置为@"",则弹框不再显示这个按钮
    @property (nonatomic, nullable, copy) NSString *localizedFallbackTitle;
    
    // 可以设置指纹弹框“取消”按钮的标题(iOS10.0以上可用),如果不设置或设置为nil或设置为@"",都显示默认的“取消”
    @property (nonatomic, nullable, copy) NSString *localizedCancelTitle NS_AVAILABLE(10_12, 10_0);
    
    // 最大指纹尝试错误次数(iOS8.3 - iOS9.0可用)
    @property (nonatomic, nullable) NSNumber *maxBiometryFailures NS_DEPRECATED_IOS(8_3, 9_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
    
    // 这个可以检测你的指纹数据库的变化,增加或者删除指纹这个属性会做出相应的反应(iOS9.0以上可用)
    @property (nonatomic, nullable, readonly) NSData *evaluatedPolicyDomainState NS_AVAILABLE(10_11, 9_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
    
    // 两次开启指纹之间的时间间隔,决定第二次是否需要指纹解锁
    @property (nonatomic) NSTimeInterval touchIDAuthenticationAllowableReuseDuration NS_AVAILABLE(NA, 9_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;
    

    二、使用方法

    1、首先,引入依赖框架 LocalAuthentication.framework

    #import <LocalAuthentication/LocalAuthentication.h>
    

    2、集成指纹解锁的方法

    - (void)evaluateAuthenticate
    {
        //iOS 8以上才支持指纹识别接口
        if ([[UIDevice currentDevice].systemVersion floatValue] < 8) {
            NSLog(@"不支持TouchID (版本必须高于iOS 8.0才能使用)");
            return;
        }
        
        //创建LAContext
        LAContext *context = [[LAContext alloc] init];
        context.localizedFallbackTitle = @"输入密码吧";
        
        NSError *Error = nil;
        
        //判断设备支持状态
        if ([context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&Error]) {
            //支持指纹验证
            [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"请验证已有手机指纹" reply:^(BOOL success, NSError *error) {
                if (success) {
                    //验证成功,主线程处理UI
                    [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                        NSLog(@"指纹验证成功");
                    }];
                } else {
                    NSLog(@"验证失败 == %@", error.localizedDescription);
                    switch (error.code) {
                        case LAErrorSystemCancel:{
                            NSLog(@"系统取消授权,如其他APP切入");
                        }
                            break;
                        case LAErrorUserCancel:{
                            NSLog(@"用户取消验证,点击了取消按钮");
                        }
                            break;
                        case LAErrorUserFallback:{
                            NSLog(@"用户取消验证,点击了输入密码按钮");
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                //用户选择输入密码,切换主线程处理
                                
                            }];
                        }
                            break;
                        case LAErrorAuthenticationFailed:{
                            NSLog(@"连续三次指纹验证失败,可能指纹模糊或用错手指");
                        }
                            break;
                        case LAErrorTouchIDLockout:{
                            NSLog(@"设备TouchID被锁定,因为失败的次数太多了");
                        }
                            break;
                        default:{
                            NSLog(@"设备TouchID不可用。。。");
                            [[NSOperationQueue mainQueue] addOperationWithBlock:^{
                                //其他情况,切换主线程处理
                            }];
                        }
                            break;
                    }
                }
            }];
        } else {
            //该设备不支持TouchID
            NSLog(@"不支持TouchID == %@", Error.localizedDescription);
            switch (Error.code) {
                case LAErrorTouchIDNotEnrolled:{
                    NSLog(@"指纹验证无法启动,因为没有录入指纹");
                }
                    break;
                case LAErrorPasscodeNotSet:{
                    NSLog(@"指纹验证无法启动,因为设备没有设置密码");
                }
                    break;
                case LAErrorTouchIDLockout:{
                    NSLog(@"设备TouchID被锁定,因为失败的次数太多了");
                }
                    break;
                default:{
                    NSLog(@"设备TouchID不可用。。。");
                }
                    break;
            }
        }
    }
    

    三、demo

    这里有我封装好的一个demo,欢迎参考!
    如有任何问题,欢迎留言!

    相关文章

      网友评论

      本文标题:iOS指纹解锁TouchID

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