Swift實現Touch ID驗證

Mr 布魯斯發表於2014-10-10

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!型別的success返回驗證結果,成功活失敗(true或false)。

相關文章