指紋解鎖的使用越來越普遍了,主要是使用方便,再用之前還是先了解一下如何使用吧。
一、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,歡迎參考!
如有任何問題,歡迎留言!