Swift利用指紋識別或面部識別為應(yīng)用添加私密保護功能
前言
從最初做應(yīng)用開始,我就密切關(guān)注用戶的反饋和評論。有時他們的要求確實并不合理,但當大多數(shù)人提到一項功能時,就該我們做產(chǎn)品的人反思了。 私密保護功能是用戶在評論中提到的,恰好像OneDay這樣比較私密的內(nèi)容確實可以增加這項功能。
指紋識別和面部識別雖然是兩個很不相同的交互,但從開發(fā)的角度他們卻只需要一套代碼就可以搞定。在做之前我先解釋下整個實現(xiàn)過程的重要環(huán)節(jié):
原理圖
1.我們需要一個數(shù)據(jù)來保存開關(guān)數(shù)據(jù),在設(shè)置中心,用戶根據(jù)喜好選擇是否開啟保護
2.一旦用戶打開應(yīng)用,通過判斷是否保護來加載遮擋頁面
3.在遮擋頁面自動實現(xiàn)解鎖過程,同時用戶也可以點擊后解鎖
4.根據(jù)機型的不同,在設(shè)置中心需要顯示不同的解鎖名稱
一、基礎(chǔ)配置工作
實現(xiàn)指紋識別與面部識別,都是通過添加LocalAuthentication Framework來實現(xiàn)的。
導(dǎo)入LocalAuthentication Framework
之后在需要用到認證的頁面,導(dǎo)入LocalAuthentication即可:
import LocalAuthentication
二、遮蓋頁創(chuàng)建與設(shè)置中心開關(guān)創(chuàng)建
在設(shè)置中心增加一欄開關(guān),暫且叫做Touch ID,最后會進行標題文字的修復(fù)。 創(chuàng)建一個單獨的遮蓋頁,只需要放置一句話及按鈕即可,按鈕將調(diào)用認證過程,文件為LockViewContrller.swift。
為了方便調(diào)用,給遮蓋頁設(shè)置了StoryBoard ID為LockController。
四、設(shè)置中心實現(xiàn)數(shù)據(jù)的修改
利用CoreData將開關(guān)的數(shù)據(jù)存儲在ifProtect中,0表示開,1表示關(guān)。 設(shè)置數(shù)據(jù)的過程不會像其他數(shù)據(jù)那樣直接改變,必須判斷是否為用戶本人進行開關(guān)。所以在SettingViewController.swift中,需要添加認證的相關(guān)函數(shù)。
1.先導(dǎo)入LocalAuthentication:
import LocalAuthentication
2.操作函數(shù):
func touchID(){ let context = LAContext() var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) { // 開始進入識別狀態(tài),以閉包形式返回結(jié)果。閉包的 success 是布爾值,代表識別成功與否。error 為錯誤信息。 context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "請用指紋解鎖", reply: {success, error in if success { // 成功之后的邏輯, 通常使用多線程來實現(xiàn)跳轉(zhuǎn)邏輯。 print("解鎖成功 success,允許設(shè)置") if self.appDelegate.mysetting.ifProtect == Int64(1){ self.appDelegate.mysetting.ifProtect = Int64(0) }else{ self.appDelegate.mysetting.ifProtect = Int64(1) } self.appDelegate.saveContext() }else { if let error = error as? NSError { // 獲取錯誤信息 let message = self.errorMessageForLAErrorCode(errorCode: error.code) print(message) } //失敗之后 print("失敗了") } self.SettingTableView.reloadData() }) } }
當是用戶本人且認證成功時,開關(guān)數(shù)據(jù)被改變;當不是用戶本人或認證不成功,開關(guān)數(shù)據(jù)不會改變。 為了保持頁面與數(shù)據(jù)統(tǒng)一,函數(shù)執(zhí)行后我們需要刷新頁面self.SettingTableView.reloadData()
。
3.獲取錯誤情況:
func errorMessageForLAErrorCode(errorCode: Int) -> String { var message = "" switch errorCode { case LAError.appCancel.rawValue: message = "Authentication was cancelled by application" case LAError.authenticationFailed.rawValue: message = "The user failed to provide valid credentials" case LAError.invalidContext.rawValue: message = "The context is invalid" case LAError.passcodeNotSet.rawValue: message = "Passcode is not set on the device" case LAError.systemCancel.rawValue: message = "Authentication was cancelled by the system" case LAError.touchIDLockout.rawValue: message = "Too many failed attempts." case LAError.touchIDNotAvailable.rawValue: message = "TouchID is not available on the device" // showPassWordInput() case LAError.userCancel.rawValue: message = "The user did cancel" case LAError.userFallback.rawValue: message = "The user chose to use the fallback" default: message = "Did not find error code on LAError object" } return message }
五、首頁加載遮蓋頁
來到首頁HomeViewController,在viewDidLoad中加入下面代碼,來判斷每一次打開應(yīng)用是否需要認證解鎖。 如果不需要,首頁可以正常顯示; 如果需要,將直接跳轉(zhuǎn)到LockController。
if self.appDelegate.mysetting.ifProtect == Int64(1){ print(self.appDelegate.mysetting.ifProtect) print("需要解鎖") if let lockVC = storyboard?.instantiateViewController(withIdentifier: "LockController") as? LockViewController { self.present(lockVC,animated: false,completion: nil) }else{ } }else{ print("不需要解鎖") }
六、在遮蓋頁中實現(xiàn)認證
遮蓋頁LockController的背景通過虛化處理,可以到達遮蓋的目的。同時擁有認證函數(shù),當認證成功后頁面自動消失返回首頁。 因為需要認證過程,因此也需要三個核心步驟。
1.導(dǎo)入LocalAuthentication:
import LocalAuthentication
2.操作函數(shù):
func touchID(){ let context = LAContext() var error: NSError? if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) { // 開始進入識別狀態(tài),以閉包形式返回結(jié)果。閉包的 success 是布爾值,代表識別成功與否。error 為錯誤信息。 context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "請用指紋解鎖", reply: {success, error in if success { // 成功之后的邏輯, 通常使用多線程來實現(xiàn)跳轉(zhuǎn)邏輯。 print("解鎖成功 success") self.dismiss(animated: true, completion: nil) }else { if let error = error as? NSError { // 獲取錯誤信息 let message = self.errorMessageForLAErrorCode(errorCode: error.code) print(message) } //失敗之后 print("失敗了") } }) } }
認證過程成功后,頁面會自動消失:self.dismiss(animated: true, completion: nil)
3.當用戶進入頁面時自動調(diào)取認證過程:
override func viewWillAppear(_ animated: Bool) { touchID() }
4.或者通過手動點擊開始認證:
@IBAction func AuthenAction(_ sender: Any) { touchID() }
5.捕獲錯誤跟設(shè)置頁面一樣。
七、根據(jù)屏幕尺寸修改開關(guān)標題
最后,我們來修復(fù)設(shè)置中心按鈕的標題文字。當判斷手機為iPhone X時,文字顯示為“面部識別”或“Touch ID”;當不是iPhone X時,顯示為“指紋識別”或“Touch ID”。這里我們用到了UIDevice來獲取了屏幕的高度:
if UIDevice().userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height == 2436 { cell.SwitchTitle.text = "Face ID" cell.SwitchImage.image = UIImage(named: "btn_setting_faceid")?.withRenderingMode(.alwaysTemplate) }else{ cell.SwitchTitle.text = "Touch ID" cell.SwitchImage.image = UIImage(named: "btn_setting_touchid")?.withRenderingMode(.alwaysTemplate) }
以上的過程便可實現(xiàn)私密保護,不過不會像系統(tǒng)解鎖那樣可以通過密碼解鎖。要實現(xiàn)密碼解鎖,還需要單獨開發(fā)該功能。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
SwiftUI學(xué)習(xí)之state和Binding的區(qū)別淺析
這篇文章主要給大家介紹了關(guān)于SwiftUI學(xué)習(xí)之state和Binding區(qū)別的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-03-03深入探究Swift枚舉關(guān)聯(lián)值的內(nèi)存
這篇文章主要給大家介紹了關(guān)于Swift枚舉關(guān)聯(lián)值的內(nèi)存的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者使用Swift具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08在 Swift 中測試 UIAlertController的方法
這篇文章主要介紹了在 Swift 中測試 UIAlertController的方法的,需要的朋友可以參考下2015-10-10Swift 3.0基礎(chǔ)學(xué)習(xí)之枚舉類型
枚舉在編程中很多時候要用到,在 Swift 中,枚舉具有更多的特性。下面這篇文章主要介紹了Swift 3.0基礎(chǔ)學(xué)習(xí)之枚舉類型的相關(guān)資料,文中介紹的非常詳細,需要的朋友可以參考借鑒,下面來一起看看吧。2017-03-03