DemoLibrary之一:【TouchID指紋識別】

由于近段時間項目告一段落啦,所以決定將近段時間接觸的一些功能集中整理總結一下,寫成了一個簡單的Demo,以供參考。此篇文章主要是介紹了第三方登錄分享以及指紋識別的配置過程:

一:指紋識別

TouchID指紋識別主要是 iPhone 5s 添加的功能設備,有了這個功能之后,極大的方便了果粉的使用,當然越來越多的應用也開始在應用中集成指紋識別功能。其實官方提供的API中可以看出,?在應用中集成也是比簡單的,主要用到的是 LocalAuthentication.framework 這個庫,當打開之后可以發現頭文件:

SDK.png
其實在這是個頭文件中看出,真正使用的接口類是LAContext.h,另外的幾個頭文件都是一些枚舉以及宏定義;下面來看一下暴露出來的幾個接口API【常用API】:

# 用來檢查當前設備是否可用touchID,返回一個BOOL值
@param  policy 是一個枚舉類型

第一個枚舉LAPolicyDeviceOwnerAuthenticationWithBiometrics就是說,用的是手指指紋去驗證的;NS_ENUM_AVAILABLE(NA, 8_0)iOS8 可用
第二個枚舉LAPolicyDeviceOwnerAuthentication少了WithBiometrics則是使用TouchID或者密碼驗證,默認是錯誤兩次指紋或者鎖定后,彈出輸入密碼界面;NS_ENUM_AVAILABLE(10_11, 9_0)iOS 9可用

- (BOOL)canEvaluatePolicy:(LAPolicy)policy error:(NSError * __autoreleasing *)error __attribute__((swift_error(none)));
調用驗證方法,注意這里的三個參數:
第一個參數policy是要使用上面那個LAPolicy的枚舉
第二個參數localizedReason是NSString類型的驗證理由
第三個參數reply則是一個回調Block,block內有一個BOOL類型的success判斷是否成功驗證,還有一個用于判斷錯誤信息的NSError類型的error
- (void)evaluatePolicy:(LAPolicy)policy
       localizedReason:(NSString *)localizedReason
                 reply:(void(^)(BOOL success, NSError * __nullable error))reply
invalidate方法用來廢止這個context
- (void)invalidate NS_AVAILABLE(10_11, 9_0)

以下是提供的幾個屬性方法

// /返回按鈕標題。允許設置密碼輸入按鈕標題。如果設置為空字符串時,按鈕會隱藏
@property (nonatomic, nullable, copy) NSString *localizedFallbackTitle;

 //取消按鈕標題。允許設置取消按鈕標題。如果設置為空字符串時,按鈕會隱藏NS_AVAILABLE(10_12, 10_0)說明10.0之后才有
@property (nonatomic, nullable, copy) NSString *localizedCancelTitle NS_AVAILABLE(10_12, 10_0);

// 設置最大允許認證失敗次數NS_DEPRECATED_IOS(8_3, 9_0),說明這個屬性在iOS 8.3被引入,在iOS 9.0被廢棄,所以如果系統版本高于9.0是無法使用的。
@property (nonatomic, nullable) NSNumber *maxBiometryFailures NS_DEPRECATED_IOS(8_3, 9_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;

// 這個跟可以檢測你的指紋數據庫的變化,增加或者刪除指紋這個屬性會做出相應的反應
@property (nonatomic, nullable, readonly) NSData *evaluatedPolicyDomainState NS_AVAILABLE(10_11, 9_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;

//因為這個屬性可以設置一個時間間隔,在時間間隔內是不需要再次錄入。默認是0秒,最長可以設置5分鐘。
@property (nonatomic) NSTimeInterval touchIDAuthenticationAllowableReuseDuration NS_AVAILABLE(NA, 9_0) __WATCHOS_UNAVAILABLE __TVOS_UNAVAILABLE;

在API中提供的方法屬性本來就不多,只要能夠理解每個方法和屬性的意義,TouchID使用起來就是得心應手的啦,下列是Demo事例中的一個簡單應用方法:

/// 檢測 指紋
/*
 1、 驗證(指紋/密碼)不能開啟的錯誤信息(指紋系統被判定為無效):
 LAErrorPasscodeNotSet : 設備密碼未設置
 LAErrorTouchIDNotAvailable : TOUCH ID不可用
 LAErrorTouchIDNotEnrolled : 指紋未錄入
 LAErrorTouchIDLockout : TOUCH ID被鎖定
 LAErrorAppCancel : APP調用了- (void)invalidate
 方法使LAContext
 失效
 LAErrorInvalidContext : 實例化的LAContext
 對象失效,再次調用evaluation...
 方法則會彈出此錯誤信息
 2、 其他錯誤信息(指紋系統判定有效,但是驗證指紋錯誤):
 LAErrorAuthenticationFailed : 鑒定失敗
 LAErrorUserCancel : 用戶取消
 LAErrorUserFallback : 用戶選擇輸入密碼
 LAErrorSystemCancel : 系統取消(如:另外一個應用進入前臺)
 
 */

/**
 *    指紋驗證解鎖的主要方法
 *
 *  @param localizedFallbackTitle  密碼輸入按鈕標題 例如:定義標題
 *  @param localizedReason    指紋解鎖彈出框副標題 例如:這是副標題
 *  @param touchBlock         結果回調
 */
-(void)touchIDWithlocalizedFallbackTitle:(NSString *)localizedFallbackTitle localizedReason:(NSString*)localizedReason success:(void(^)(BOOL success, NSString *errorMsg)) touchBlock{
    
    [SVProgressHUD show];
    
    LAContext *context = [[LAContext alloc]init];//使用 new 不會給一些屬性初始化賦值
        
    if (!localizedReason) {
        localizedReason = @"請驗證已有指紋";
    }
    
    context.localizedFallbackTitle = localizedFallbackTitle ? : @"密碼登錄";//@""可以不讓 feedBack 按鈕顯示
    
    NSError * err;
    
    self.canUseTouchId = [context canEvaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics error:&err];
    // 指紋識別被鎖定,需要輸入密碼驗證
    if (err.code == LAErrorTouchIDLockout) {
        
        [SVProgressHUD dismiss];
        
        if (touchBlock) {
            touchBlock(NO,@"Touch ID被鎖,需要用戶輸入密碼解鎖");
        }
        return;
    }
    
    if (self.canUseTouchId) {// 檢測手機是否可以使用TouchId
        

        //LAPolicyDeviceOwnerAuthenticationWithBiometrics
        [context evaluatePolicy:LAPolicyDeviceOwnerAuthenticationWithBiometrics localizedReason:localizedReason reply:^(BOOL success, NSError * _Nullable error) {
            
            [SVProgressHUD dismiss];

            //SVProgressHUD dismiss 需要 0.15才會消失;所以dismiss 后進行下一步操作;但是0.3是適當延長時間;留點余量
            dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3* NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                
                self.completeMsg = nil;
                
                if (success){
                    
                    NSLog(@"指紋識別成功");
                    // 指紋識別成功,回主線程更新UI
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //成功操作
                        self.completeMsg = @"指紋識別成功";
                        
                        if (touchBlock) {
                            touchBlock(success,self.completeMsg);
                        }
                        
                    });
                }
                
                if (error) {
                    //指紋識別失敗,回主線程更新UI
                    dispatch_async(dispatch_get_main_queue(), ^{
                        //失敗操作
                        LAError errorCode = error.code;
                        
                        switch (errorCode) {
                                
                            case LAErrorAuthenticationFailed:
                            {
                                NSLog(@"授權失敗"); // -1 連續三次指紋識別錯誤
                                self.completeMsg = @"授權失敗";
                            }
                                break;
                            case LAErrorUserCancel: // Authentication was canceled by user (e.g. tapped Cancel button)
                            {
                                NSLog(@"用戶取消驗證Touch ID"); // -2 在TouchID對話框中點擊了取消按鈕
                                self.completeMsg = @"用戶取消驗證Touch ID";
                                
                            }
                                break;
                            case LAErrorUserFallback: // Authentication was canceled, because the user tapped the fallback button (Enter Password)
                            {
                                NSLog(@"用戶選擇輸入密碼,切換主線程處理"); // -3 在TouchID對話框中點擊了輸入密碼按鈕
                                self.completeMsg = @"用戶選擇輸入密碼,切換主線程處理";
                                
                            }
                                break;
                            case LAErrorSystemCancel: // Authentication was canceled by system (e.g. another application went to foreground)
                            {
                                NSLog(@"取消授權,如其他應用切入"); // -4 TouchID對話框被系統取消,例如按下Home或者電源鍵
                                self.completeMsg = @"取消授權,如其他應用切入";
                                
                            }
                                break;
                            case LAErrorPasscodeNotSet: // Authentication could not start, because passcode is not set on the device.
                                
                            {
                                NSLog(@"設備系統未設置密碼"); // -5
                                self.completeMsg = @"設備系統未設置密碼";
                                
                            }
                                break;
                            case LAErrorTouchIDNotAvailable: // Authentication could not start, because Touch ID is not available on the device
                            {
                                NSLog(@"設備未設置Touch ID"); // -6
                                self.completeMsg = @"設備未設置Touch ID";
                                
                            }
                                break;
                            case LAErrorTouchIDNotEnrolled: // Authentication could not start, because Touch ID has no enrolled fingers
                            {
                                NSLog(@"用戶未錄入指紋"); // -7
                                self.completeMsg = @"用戶未錄入指紋";
                                
                            }
                                break;
                            case LAErrorTouchIDLockout: //Authentication was not successful, because there were too many failed Touch ID attempts and Touch ID is now locked. Passcode is required to unlock Touch ID, e.g. evaluating LAPolicyDeviceOwnerAuthenticationWithBiometrics will ask for passcode as a prerequisite 用戶連續多次進行Touch ID驗證失敗,Touch ID被鎖,需要用戶輸入密碼解鎖,先Touch ID驗證密碼
                            {
                                NSLog(@"Touch ID被鎖,需要用戶輸入密碼解鎖"); // -8 連續五次指紋識別錯誤,TouchID功能被鎖定,下一次需要輸入系統密碼
                                self.completeMsg = @"Touch ID被鎖,需要用戶輸入密碼解鎖";
                                
                            }
                                break;
                            case LAErrorAppCancel: // Authentication was canceled by application (e.g. invalidate was called while authentication was in progress) 如突然來了電話,電話應用進入前臺,APP被掛起啦");
                            {
                                NSLog(@"用戶不能控制情況下APP被掛起"); // -9
                                self.completeMsg = @"用戶不能控制情況下APP被掛起";
                                
                            }
                                break;
                            case LAErrorInvalidContext: // LAContext passed to this call has been previously invalidated.
                            {
                                NSLog(@"LAContext傳遞給這個調用之前已經失效"); // -10
                                self.completeMsg = @"指紋識別失效";
                                
                            }
                                break;
                        }
                        
                        if (touchBlock) {
                            touchBlock(success,self.completeMsg);
                        }
                        
                    });
                }
                
            });
        }];
        
    }else{
        
        [SVProgressHUD dismiss];

        if (touchBlock) {
            touchBlock(NO,[NSString stringWithFormat:@"設備不支持指紋解鎖-- %@",err.localizedFailureReason ? : @""]);
        }
    }
    
}

效果圖如下:

解鎖頁面
自定義密碼輸入標題、副標題.png
取消.PNG
TouchID鎖定.PNG
識別成功.PNG

TouchID的簡單集成使用功能就是這樣,如果想要了解更詳細的內容,可以具體參考蘋果官方文檔:

lacontext官方文檔

https://developer.apple.com/reference/localauthentication/lacontext

TouchID官方文檔:

https://developer.apple.com/reference/localauthentication/lacontext

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容