iOS開發(fā)指紋驗(yàn)證touch ID

在開始代碼之前英融,先認(rèn)識(shí)一下LAPolicy棘伴。

LAPolicy是一個(gè)枚舉趁耗,有兩個(gè)值

LAPolicyDeviceOwnerAuthenticationWithBiometrics // 用手指指紋去驗(yàn)證,iOS8.0以上可用
LAPolicyDeviceOwnerAuthentication // 使用TouchID或者密碼驗(yàn)證,默認(rèn)是錯(cuò)誤三次指紋或者鎖定后,彈出輸入密碼界面iOS 9.0以上可用

第一個(gè)枚舉值,用戶驗(yàn)證失敗3次大脉,會(huì)返回錯(cuò)誤碼LAErrorAuthenticationFailed搞监,如果驗(yàn)證失敗5次會(huì)返回錯(cuò)誤碼LAErrorTouchIDLockout并且指紋驗(yàn)證功能被鎖。如果在系統(tǒng)密碼驗(yàn)證的時(shí)候取消镰矿,下次再打開指紋驗(yàn)證功能會(huì)發(fā)現(xiàn)沒有指紋驗(yàn)證功能琐驴。

第二個(gè)枚舉值,用戶驗(yàn)證失敗3次會(huì)自動(dòng)彈出系統(tǒng)密碼驗(yàn)證衡怀,如果系統(tǒng)密碼驗(yàn)證通過也算成功棍矛。如果在系統(tǒng)密碼驗(yàn)證的時(shí)候取消,下次再打開指紋驗(yàn)證功能依然會(huì)驗(yàn)證系統(tǒng)密碼抛杨,而不是驗(yàn)證指紋够委。

因?yàn)長APolicy有兩種不同類型,下面就以兩種方式分別來實(shí)現(xiàn)指紋驗(yàn)證怖现。

首先導(dǎo)入框架#import <LocalAuthentication/LocalAuthentication.h>

聲明LAContext屬性

//本地認(rèn)證上下文聯(lián)系對象
@property(nonatomic,strong) LAContext * context;

代碼:

方式一

初始化對象茁帽,并驗(yàn)證是否有指紋驗(yàn)證功能

//本地認(rèn)證上下文聯(lián)系對象,每次使用指紋識(shí)別驗(yàn)證功能都要重新初始化屈嗤,否則會(huì)一直顯示驗(yàn)證成功潘拨。
    self.context = [[LAContext alloc] init];
    NSError * error = nil;
    //驗(yàn)證是否具有指紋認(rèn)證功能
    BOOL canEvaluatePolicy = [_context canEvaluatePolicy:LAPolicyDeviceOwnerAuthentication error:&error];
    if (error) {
        NSLog(@"%@", error.localizedDescription);
    }
    
    if (canEvaluatePolicy) {
        NSLog(@"有指紋認(rèn)證功能");
        
        // 指紋認(rèn)證錯(cuò)誤后的第二個(gè)按鈕文字(不寫默認(rèn)為“輸入密碼”)
        _context.localizedFallbackTitle = @"芝麻開門";
        
        // 調(diào)用指紋驗(yàn)證
        [self beginTouchId1];
        
    } else {
        NSLog(@"無指紋認(rèn)證功能");
    }

開始指紋驗(yàn)證

- (void)beginTouchId1{
    [_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:@"驗(yàn)證指紋以確認(rèn)您的身份" reply:^(BOOL success, NSError *error) {
        
        // 切換到主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (success) {
                NSLog(@"指紋驗(yàn)證成功");
            } else {
                NSLog(@"指紋認(rèn)證失敗,%@",error.description);
                NSLog(@"%ld", (long)error.code);
                // 錯(cuò)誤碼 error.code
                switch (error.code) {
                        
                    case LAErrorUserCancel: { NSLog(@"用戶取消驗(yàn)證Touch ID");// -2 在TouchID對話框中點(diǎn)擊了取消按鈕或者按了home鍵
                    }
                        break;
                        
                    case LAErrorUserFallback: {
                        
                        NSLog(@"用戶選擇輸入密碼"); // -3 在TouchID對話框中點(diǎn)擊了輸入密碼按鈕
                    }
                        break;
                        
                    case LAErrorSystemCancel: { NSLog(@"取消授權(quán)饶号,如其他應(yīng)用切入铁追,用戶自主"); // -4 TouchID對話框被系統(tǒng)取消,例如按下電源鍵
                    }
                        break;
                        
                    case LAErrorPasscodeNotSet: {
                        NSLog(@"設(shè)備系統(tǒng)未設(shè)置密碼"); // -5
                    }
                        break;
                        
                    case LAErrorTouchIDNotAvailable: {
                        
                        NSLog(@"設(shè)備未設(shè)置Touch ID"); // -6
                    }
                        break;
                        
                    case LAErrorTouchIDNotEnrolled:  {
                        
                        NSLog(@"用戶未錄入指紋"); // -7
                    }
                        break;
                        
                    case LAErrorAppCancel: {
                        NSLog(@"用戶不能控制情況下APP被掛起"); // -9
                    }
                        break;
                        
                    case LAErrorInvalidContext: {
                        
                        NSLog(@"LAContext傳遞給這個(gè)調(diào)用之前已經(jīng)失效"); // -10
                    }
                        break;
                        
                    default: {
                        NSLog(@"其他情況");
                    }
                        break;
                }
            }
        });
    }];
}
參數(shù)解釋:

localizedFallbackTitle屬性設(shè)置的是指紋驗(yàn)證錯(cuò)誤后第二個(gè)按鈕的文字茫船。

localizedFallbackTitle屬性不設(shè)置或者設(shè)置為nil琅束,第二個(gè)按鈕默認(rèn)標(biāo)題為輸入密碼。

默認(rèn)標(biāo)題.png

如果想自定義第二個(gè)按鈕的標(biāo)題算谈,就為localizedFallbackTitle屬性設(shè)置值涩禀。_context.localizedFallbackTitle = @"芝麻開門";

自定義標(biāo)題.png

如果不想有第二個(gè)按鈕的話,可以把localizedFallbackTitle設(shè)置為空字符串然眼。_context.localizedFallbackTitle = @"";

沒有第二個(gè)按鈕.png

調(diào)用指紋驗(yàn)證功能核心代碼:

- (void)evaluatePolicy:(LAPolicy)policy
       localizedReason:(NSString *)localizedReason
                 reply:(void(^)(BOOL success, NSError * __nullable error))reply;

第一個(gè)參數(shù)policy是枚舉艾船,有兩個(gè)值,詳細(xì)解釋看文章開頭部分:

LAPolicyDeviceOwnerAuthenticationWithBiometrics // 用手指指紋去驗(yàn)證,iOS8.0以上可用
LAPolicyDeviceOwnerAuthentication // 使用TouchID或者密碼驗(yàn)證,默認(rèn)是錯(cuò)誤三次指紋或者鎖定后,彈出輸入密碼界面iOS 9.0以上可用

第二個(gè)參數(shù)localizedReason(驗(yàn)證理由)是指彈出驗(yàn)證框的第二個(gè)標(biāo)題高每,可根據(jù)項(xiàng)目需求自定義屿岂。第一個(gè)標(biāo)題不可更改。

驗(yàn)證原因.png

第三個(gè)參數(shù)reply是回調(diào)處理鲸匿。內(nèi)含兩個(gè)回調(diào)參數(shù)success和error雁社。
success是BOOL值,YES表示驗(yàn)證成功晒骇,NO表示驗(yàn)證失敗。
error是一個(gè)枚舉,總共十個(gè)錯(cuò)誤的類型洪囤,在驗(yàn)證失敗后返回徒坡。

typedef NS_ENUM(NSInteger, LAError)
{
    LAErrorAuthenticationFailed,   // -1驗(yàn)證信息出錯(cuò),就是說你指紋不對
    LAErrorUserCancel              // -2用戶取消了驗(yàn)證
    LAErrorUserFallback            // -3用戶點(diǎn)擊了手動(dòng)輸入密碼的按鈕瘤缩,所以被取消了
    LAErrorSystemCancel            // -4被系統(tǒng)取消喇完,就是說你現(xiàn)在進(jìn)入別的應(yīng)用了,不在剛剛那個(gè)頁面剥啤,所以沒法驗(yàn)證
    LAErrorPasscodeNotSet          // -5用戶沒有設(shè)置TouchID
    LAErrorTouchIDNotAvailable     // -6用戶設(shè)備不支持TouchID
    LAErrorTouchIDNotEnrolled      // -7用戶沒有設(shè)置手指指紋
    LAErrorTouchIDLockout          // -8用戶錯(cuò)誤次數(shù)太多废菱,現(xiàn)在被鎖住了
    LAErrorAppCancel               // -9在驗(yàn)證中被其他app中斷
    LAErrorInvalidContext          // -10請求驗(yàn)證出錯(cuò)
} NS_ENUM_AVAILABLE(10_10, 8_0);

------------------------------我是分割線------------------------

方式二

初始化對象即纲,并驗(yàn)證是否有指紋驗(yàn)證功能

//本地認(rèn)證上下文聯(lián)系對象,每次使用指紋識(shí)別驗(yàn)證功能都要重新初始化,否則會(huì)一直顯示驗(yàn)證成功驻襟。
    self.context = [[LAContext alloc] init];
    NSError * error = nil;
    //驗(yàn)證是否具有指紋認(rèn)證功能
    BOOL canEvaluatePolicy = [_context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&error];
    if (error) {
        NSLog(@"%@", error.localizedDescription);
    }
    
    
    if (canEvaluatePolicy) {
        NSLog(@"有指紋認(rèn)證功能");
        
        // 指紋認(rèn)證錯(cuò)誤后的第二個(gè)按鈕文字(不寫默認(rèn)為“輸入密碼”)
        _context.localizedFallbackTitle = @"芝麻開門";
        
        // 調(diào)用指紋驗(yàn)證
        [self beginTouchId];
        
    } else {
        NSLog(@"無指紋認(rèn)證功能");
        // 沒有指紋認(rèn)證功能有可能是輸入錯(cuò)誤次數(shù)達(dá)到5次,認(rèn)證功能被鎖導(dǎo)致吆玖。
        BOOL isLock = (BOOL)[[NSUserDefaults standardUserDefaults] objectForKey:@"touchIdIsLocked"];
        if (isLock) {
            // 認(rèn)證被鎖處理
            [self touchIdIsLocked];
        }
    }

開始指紋驗(yàn)證

- (void)beginTouchId{
    [_context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:@"驗(yàn)證指紋以確認(rèn)您的身份" reply:^(BOOL success, NSError *error) {
        
        // 切換到主線程
        dispatch_async(dispatch_get_main_queue(), ^{
            
            if (success) {
                NSLog(@"指紋驗(yàn)證成功");
            } else {
                NSLog(@"指紋認(rèn)證失敗抒抬,%@",error.description);
                NSLog(@"%ld", (long)error.code);
                // 錯(cuò)誤碼 error.code
                switch (error.code) {
                    case LAErrorAuthenticationFailed:{
                        NSLog(@"授權(quán)失敗"); // -1 連續(xù)三次指紋識(shí)別錯(cuò)誤
                    }
                        break;
                        
                    case LAErrorUserCancel: { NSLog(@"--用戶取消驗(yàn)證Touch ID");// -2 在TouchID對話框中點(diǎn)擊了取消按鈕或者按了home鍵
                    }
                        break;
                        
                    case LAErrorUserFallback: {
                        
                        NSLog(@"用戶選擇輸入密碼"); // -3 在TouchID對話框中點(diǎn)擊了輸入密碼按鈕,在這里可以做一些自定義的操作。
                    }
                        break;
                        
                    case LAErrorSystemCancel: { NSLog(@"取消授權(quán)冲簿,如其他應(yīng)用切入粟判,用戶自主"); // -4 TouchID對話框被系統(tǒng)取消,例如按下電源鍵
                    }
                        break;
                        
                    case LAErrorPasscodeNotSet: {
                        NSLog(@"設(shè)備系統(tǒng)未設(shè)置密碼"); // -5
                    }
                        break;
                        
                    case LAErrorTouchIDNotAvailable: {
                        
                        NSLog(@"設(shè)備未設(shè)置Touch ID"); // -6
                    }
                        break;
                        
                    case LAErrorTouchIDNotEnrolled:  {
                        
                        NSLog(@"用戶未錄入指紋"); // -7
                    }
                        break;
                        
                    case LAErrorTouchIDLockout: {
                        // -8 連續(xù)五次指紋識(shí)別錯(cuò)誤峦剔,TouchID功能被鎖定档礁,下一次需要輸入系統(tǒng)密碼
                        NSLog(@"Touch ID被鎖,需要用戶輸入系統(tǒng)密碼解鎖");
                        // 往本地用戶偏好設(shè)置里把touchIdIsLocked標(biāo)識(shí)設(shè)置為yes吝沫,表示指紋識(shí)別被鎖
                        [[NSUserDefaults standardUserDefaults] setObject:@(YES)forKey:@"touchIdIsLocked"];
                        [[NSUserDefaults standardUserDefaults] synchronize];
                        [self touchIdIsLocked];
                    }
                        break;
                        
                    case LAErrorAppCancel: {
                        NSLog(@"用戶不能控制情況下APP被掛起"); // -9
                    }
                        break;
                        
                    case LAErrorInvalidContext: {
                        
                        NSLog(@"LAContext傳遞給這個(gè)調(diào)用之前已經(jīng)失效"); // -10
                    }
                        break;
                        
                    default: {
                        NSLog(@"其他情況");
                    }
                        break;
                }
            }
        });
    }];
}

指紋驗(yàn)證被鎖處理

- (void)touchIdIsLocked{
    [_context evaluatePolicy:LAPolicyDeviceOwnerAuthentication localizedReason:@"驗(yàn)證密碼" reply:^(BOOL success, NSError * _Nullable error) {
        if (success) {
            NSLog(@"驗(yàn)證成功");
            // 把本地標(biāo)識(shí)改為NO呻澜,表示指紋解鎖解除鎖定
            [[NSUserDefaults standardUserDefaults] setObject:@(NO) forKey:@"touchIdIsLocked"];
            [[NSUserDefaults standardUserDefaults] synchronize];
        }else{
            NSLog(@"驗(yàn)證失敗");
        }
    }];
}

-------------------------------我是分割線-------------------------

兩種方式的比較

1.方式一少了三個(gè)錯(cuò)誤碼,LAErrorUserFallback(用戶選擇輸入密碼)野舶,LAErrorAuthenticationFailed(連續(xù)三次指紋識(shí)別錯(cuò)誤)和LAErrorTouchIDLockout(連續(xù)五次指紋識(shí)別錯(cuò)誤易迹,TouchID功能被鎖定)。
what?沒有LAErrorUserFallback(用戶選擇輸入密碼)平道,如果用戶點(diǎn)擊了輸入密碼按鈕會(huì)怎么辦呢睹欲?不要急,這時(shí)候會(huì)自動(dòng)調(diào)起輸入系統(tǒng)密碼功能的一屋。
沒有LAErrorAuthenticationFailed(連續(xù)三次指紋識(shí)別錯(cuò)誤)和LAErrorTouchIDLockout(連續(xù)五次指紋識(shí)別錯(cuò)誤窘疮,TouchID功能被鎖定)錯(cuò)誤碼是因?yàn)樵诜绞揭恢兄讣y驗(yàn)證連續(xù)錯(cuò)誤3次就自動(dòng)調(diào)起系統(tǒng)密碼驗(yàn)證功能。

2.方式二在指紋驗(yàn)證連續(xù)錯(cuò)誤3次的情況下會(huì)先返回錯(cuò)誤碼LAErrorAuthenticationFailed冀墨。如果有業(yè)務(wù)需求闸衫,可以在這里做一些提示或其他功能。連續(xù)錯(cuò)誤5次會(huì)返回錯(cuò)誤碼LAErrorTouchIDLockout诽嘉,此時(shí)指紋驗(yàn)證功能會(huì)被鎖死蔚出,如果在這里不做操作弟翘,再次使用指紋驗(yàn)證功能就會(huì)顯示無指紋驗(yàn)證功能。只有當(dāng)手機(jī)鎖屏后骄酗,再次開屏稀余,輸入系統(tǒng)密碼才能解鎖。在上面代碼例子里趋翻,我在這里做了調(diào)起系統(tǒng)密碼驗(yàn)證功能的操作睛琳。

3.很顯然方式一比方式二更簡單方便。如果沒有特殊的業(yè)務(wù)需求踏烙,推薦用方式一來實(shí)現(xiàn)指紋識(shí)別功能师骗。

小知識(shí):

1.指紋驗(yàn)證功能被鎖是通用的,也就是說在一個(gè)地方指紋驗(yàn)證功能被鎖了讨惩,在其他地方的指紋驗(yàn)證都會(huì)被鎖起來辟癌。

2.連續(xù)5次輸入系統(tǒng)密碼錯(cuò)誤后 會(huì)被鎖一分鐘

系統(tǒng)密碼5次錯(cuò)誤被鎖.png

demo下載地址: https://github.com/jiangbin1993/touchID.git

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市步脓,隨后出現(xiàn)的幾起案子愿待,更是在濱河造成了極大的恐慌,老刑警劉巖靴患,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件仍侥,死亡現(xiàn)場離奇詭異,居然都是意外死亡鸳君,警方通過查閱死者的電腦和手機(jī)农渊,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來或颊,“玉大人砸紊,你說我怎么就攤上這事〈烟簦” “怎么了醉顽?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長平挑。 經(jīng)常有香客問我游添,道長,這世上最難降的妖魔是什么通熄? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任唆涝,我火速辦了婚禮,結(jié)果婚禮上唇辨,老公的妹妹穿的比我還像新娘廊酣。我一直安慰自己,他們只是感情好赏枚,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布亡驰。 她就那樣靜靜地躺著晓猛,像睡著了一般。 火紅的嫁衣襯著肌膚如雪凡辱。 梳的紋絲不亂的頭發(fā)上鞍帝,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天,我揣著相機(jī)與錄音煞茫,去河邊找鬼。 笑死摄凡,一個(gè)胖子當(dāng)著我的面吹牛续徽,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亲澡,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼钦扭,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了床绪?” 一聲冷哼從身側(cè)響起客情,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎癞己,沒想到半個(gè)月后膀斋,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡痹雅,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年仰担,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片绩社。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡摔蓝,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愉耙,到底是詐尸還是另有隱情贮尉,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布朴沿,位于F島的核電站猜谚,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏悯仙。R本人自食惡果不足惜龄毡,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望锡垄。 院中可真熱鬧沦零,春花似錦、人聲如沸货岭。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至屯仗,卻和暖如春搞坝,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背魁袜。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工桩撮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人峰弹。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓店量,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鞠呈。 傳聞我的和親對象是個(gè)殘疾皇子融师,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 簡述: 在類似支付寶為首的應(yīng)用以及各種理財(cái)?shù)壬婕板X財(cái)對安全性要求較高的應(yīng)用中,目前普遍對關(guān)鍵數(shù)據(jù)都做了安全訪問限制...
    C_HPY閱讀 2,928評論 0 18
  • 最近做項(xiàng)目版本更新有個(gè)需求是 3DTouch解鎖功能蚁吝, 由此原因接觸 Apple的指紋解鎖功能旱爆, 基本功能原先已經(jīng)...
    JerseyBro閱讀 1,360評論 0 4
  • iOS 8 SDK向開發(fā)者公開了Touch ID指紋識(shí)別功能,允許App對用戶身份進(jìn)行本地驗(yàn)證窘茁。使用TouchID...
    走在路上的小二閱讀 916評論 0 4
  • error code(錯(cuò)誤代碼)=2000是無效的像素格式怀伦。error code(錯(cuò)誤代碼)=2001是指定的驅(qū)動(dòng)...
    Heikki_閱讀 1,771評論 0 4
  • 我從7歲開始聽收音機(jī),至今已有快四十年的歷史庙曙。收音機(jī)是我的音樂啟蒙空镜,我對音樂的絕大多數(shù)體驗(yàn)都是來自收音機(jī),在收音機(jī)...
    薇薇安的30天閱讀 672評論 4 3