iOS 8 中如何用 Swift 實現 Touch ID 驗證
iOS8開放了很多API,包括HomeKit、HealthKit什麼的。我們這裡要說的是其中之一的Touch ID驗證。
以前用app保護使用者的隱私內容,只能設定和輸入密碼。眼看著只能是iPhone本身用Touch ID方便酷炫的解鎖而自己的app不能。實在讓人捉急。現在咱也可以酷炫一把了。當使用者開啟使用了Touch ID認證的app查看什麼內容的時候就只能是把手指放在Home鍵上去驗證身份。在app中驗證的指紋就是使用者在手機裡的指紋。是的,你的app無需使用者 再輸入一次驗證用的指紋了。所以使用起來還是很方便的。不過你要做好其他的準備。就像iPhone解鎖少不了密碼輸入一樣。使用者如果沒有開啟Touch ID咱的app也不能扒瞎不是?
如題所述,這個項目使用Swift來實現的。如果你的swift不熟的話,需要略微補補腦哦。
說了這麼多,看看效果吧
看到了吧。只要把大拇指放在Home鍵上就會解鎖了。
介面布局是這樣的:
這裡是通過點擊按鈕觸發驗證的。點了Authenticate按鈕之後彈出第一張圖的驗證提示。
好啦,進入正題。
首先建立一個項目。名字啊什麼的就隨你的便了都可以。但是程式設計語言,這裡需要選擇Swift。既然xcode6.0.1已經號稱提供了對swift 的全面支援。那我們就直接上swift了。實在不行還可以通過蘋果提供的機制調用已有的ObjC代碼。總之五個字:這都不是事。而且swfit本來也可以 省很多的代碼量。項目的其他的地方保持預設選擇就可以。也就是我們省點事,直接用storyboard就好了。雖然其實沒有什麼介面元素可以省略了。。。
在建立好的項目裡,選擇Build Phases。把LocalAuthentication的framework引入項目。到這裡項目的設定就可以了。
在代碼中import引入的framework。
- import LocalAuthentication
接下來建立一個按鈕:
- var authButton: UIButton = UIButton.buttonWithType(UIButtonType.System) as UIButton
- authButton.frame = CGRect(x: 100, y: screenHeight / 2, width: 100, height: 30)
- authButton.setTitle("Authenticate", forState: UIControlState.Normal)
這裡是建立按鈕的代碼。首先建立一個和系統同類型的按鈕。UIButton.buttonWithType(UIButtonType.System)返回的是一個AnyObject類型的對象,所以需要強制類型轉換成UIButon的。AnyObject和Any這兩個類型會經常遇到。主要是為了和ObjC之前的代碼想相容。所以也會經常的用is或者as操作符檢測和強制類型轉換。
- AnyObject是指任何一個class類型的執行個體
- Any是指任何一個類型的執行個體
比如,AnyObject數組可以存放任意某個class類型的執行個體。這些執行個體都是class類型,而且是同一個類型的。Any的數組則可以放任意類型的執行個體,而且這些數群組成員的類型不一定是一樣的。
建立UIButton的代碼和之前用OC的方式沒有什麼太大的區別。只不過換成了swift的文法。有了按鈕以後,也就該設定按鈕點擊事件的處理方法了。還記得不addTarget:
- authButton.addTarget(self, action: Selector("addPassAction:"), forControlEvents: UIControlEvents.TouchUpInside)
先看看addTarget的聲明:func addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents) 對 應在方法的調用中可以看到self就是AnyObject的target,不用多說什麼了。後面的action是一個Selector的結構體 struct)。我們在調用的時候初始化了一個Selector的結構體。這個參數也可以直接給出action的字串,而不用初始化Selector 這個結構體。這裡涉及到了一個類型自動轉換的知識點。Selector的建構函式需要提供一個字串作為參數,所以如果直接給出字串的時候編譯器會直接 把這個字串作為參數初始化一個Selector的結構體出來。Selector的字串內容中,最後是一個冒號“:”,和ObjC的寫法一樣的。冒號說 明方法有一個參數。最後是UIControlEvents的枚舉類型。這裡總於不用每次都寫的那麼長了。
然後,實現Selector:
- func addPassAction(sender:UIButton!){
- println("add pass action")
-
- var laContext = LAContext()
- var authError : NSError?
- var errorReason = "keep things secret"
-
- if laContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError){
- laContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: errorReason, reply: {
- (success, error) in
- if success {
- println("succeed")
- }
- else{
- println("failed")
- }
- })
- }
- else{
- var alert = UIAlertView(title: "Can not do authenticatation", message: "", delegate: nil, cancelButtonTitle: "Cancel")
- }
- }
這裡最重要的就是Touch ID驗證的功能了。var laContext = LAContext()用到了類型推斷。給變數初始化的執行個體是什麼類型的,這個變數就自動推斷為是那個類型。var authError : NSError? 類 型推斷和optional value。optional value就是在類型的後面加了一個問號。表示這個值可以是某個執行個體也可以是nil。注意:swift的nil和ObjC的nil是兩回事。ObjC的 nil是參考型別的一個空值。swift的nil就是說此變數沒有值,是不是參考型別都可以。var errorReason = "keep things secret"這個字串是要在介面中現實的。所以絕對不可以為空白!
laContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError)檢查裝置是不是可以用biometrics的方法驗證身份。就是看看能不能指紋解鎖。沒有硬體,或者有硬體沒設定好指紋的都是不可以驗證的。好的,如果已經設定好了指紋,那麼就可以解鎖了。
- laContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: errorReason, reply: {
-
- (success, error) in
-
- if success {
-
- println("succeed")
-
- }
-
- else{
-
- println("failed")
-
- }
-
- })
後面的replay參數是一個傳回值為空白的closure。這個closure的參數是bool和NSError!closure的一般形式是{(參數1, 參數2)->傳回值類型 in //代碼}success返 回驗證結果,成功活失敗true或false)。這時,根據驗證的成功或者失敗,替換掉println("succeed")或者 println("failed")語句,實現你需要實現的功能。比如,進入app的功能詳細頁等用Touch ID保護的資訊。如果無法驗證,就跳轉到密碼驗證部分。這樣使用者在指紋驗證無法進行的情況下還可以通過輸入密碼進入到app的功能部分。
就到這裡了。寫個項目試試吧!