iOS指纹解锁TouchID


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

一、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,欢迎参考!
如有任何问题,欢迎留言!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,029评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,395评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,570评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,535评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,650评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,850评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,006评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,747评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,207评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,536评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,683评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,342评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,964评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,772评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,004评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,401评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,566评论 2 349

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 171,799评论 25 707
  • 简述: 在类似支付宝为首的应用以及各种理财等涉及钱财对安全性要求较高的应用中,目前普遍对关键数据都做了安全访问限制...
    C_HPY阅读 2,944评论 0 18
  • 正确的认识曝光 按下快门按钮,在快门启动的瞬间,光线通过光圈的光孔使数码相机的传感器或传统相机的胶片感光,这就是摄...
    奥哈阅读 813评论 0 7
  • “一向年光有限身,等闲离别易伤魂。酒筵歌席莫辞频。 满目山河空念远,落花风雨更伤春。不如怜取眼前人。”这是晏殊的一...
    忆言如晤阅读 416评论 0 5
  • 阳光柔了不少,温暖似乎盈满了时光的间隙,一切都变得那样虚幻。 西瓜带着口罩,穿着一身休闲装,挺拔的身材和清俊的面庞...
    尘世若沫or梓尽言沐阅读 136评论 0 0