iOS 8 中如何用 Swift 實現(xiàn) Touch ID 驗證
iOS8開放了很多API,包括HomeKit、HealthKit什么的。我們這里要說的是其中之一的Touch ID驗證。
以前用app保護用戶的隱私內(nèi)容,只能設(shè)定和輸入密碼。眼看著只能是iPhone本身用Touch ID方便酷炫的解鎖而自己的app不能。實在讓人捉急?,F(xiàn)在咱也可以酷炫一把了。當用戶打開使用了Touch ID認證的app查看什么內(nèi)容的時候就只能是把手指放在Home鍵上去驗證身份。在app中驗證的指紋就是用戶在手機里的指紋。是的,你的app無需用戶 再輸入一次驗證用的指紋了。所以使用起來還是很方便的。不過你要做好其他的準備。就像iPhone解鎖少不了密碼輸入一樣。用戶如果沒有開啟Touch ID咱的app也不能扒瞎不是?
如題所述,這個項目使用Swift來實現(xiàn)的。如果你的swift不熟的話,需要略微補補腦哦。
說了這么多,看看效果吧
看到了吧。只要把大拇指放在Home鍵上就會解鎖了。
界面布局是這樣的:
這里是通過點擊按鈕觸發(fā)驗證的。點了Authenticate按鈕之后彈出***張圖的驗證提示。
好啦,進入正題。
首先創(chuàng)建一個項目。名字啊什么的就隨你的便了都可以。但是編程語言,這里需要選擇Swift。既然xcode6.0.1已經(jīng)號稱提供了對swift 的全面支持。那我們就直接上swift了。實在不行還可以通過蘋果提供的機制調(diào)用已有的ObjC代碼??傊鍌€字:這都不是事。而且swfit本來也可以 省很多的代碼量。項目的其他的地方保持默認選擇就可以。也就是我們省點事,直接用storyboard就好了。雖然其實沒有什么界面元素可以省略了。。。
在創(chuàng)建好的項目里,選擇Build Phases。把LocalAuthentication的framework引入項目。到這里項目的設(shè)置就可以了。
在代碼中import引入的framework。
- import LocalAuthentication
接下來創(chuàng)建一個按鈕:
- 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)
這里是創(chuàng)建按鈕的代碼。首先創(chuàng)建一個和系統(tǒng)同類型的按鈕。UIButton.buttonWithType(UIButtonType.System)返回的是一個AnyObject類型的對象,所以需要強制類型轉(zhuǎn)換成UIButon的。AnyObject和Any這兩個類型會經(jīng)常遇到。主要是為了和ObjC之前的代碼想兼容。所以也會經(jīng)常的用is或者as操作符檢測和強制類型轉(zhuǎn)換。
- AnyObject是指任何一個class類型的實例
- Any是指任何一個類型的實例
比如,AnyObject數(shù)組可以存放任意某個class類型的實例。這些實例都是class類型,而且是同一個類型的。Any的數(shù)組則可以放任意類型的實例,而且這些數(shù)組成員的類型不一定是一樣的。
創(chuàng)建UIButton的代碼和之前用OC的方式?jīng)]有什么太大的區(qū)別。只不過換成了swift的語法。有了按鈕以后,也就該設(shè)定按鈕點擊事件的處理方法了。還記得不addTarget:
- authButton.addTarget(self, action: Selector("addPassAction:"), forControlEvents: UIControlEvents.TouchUpInside)
先看看addTarget的聲明:func addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents) 對 應在方法的調(diào)用中可以看到self就是AnyObject的target,不用多說什么了。后面的action是一個Selector的結(jié)構(gòu)體 (struct)。我們在調(diào)用的時候初始化了一個Selector的結(jié)構(gòu)體。這個參數(shù)也可以直接給出action的字符串,而不用初始化Selector 這個結(jié)構(gòu)體。這里涉及到了一個類型自動轉(zhuǎn)換的知識點。Selector的構(gòu)造函數(shù)需要提供一個字符串作為參數(shù),所以如果直接給出字符串的時候編譯器會直接 把這個字符串作為參數(shù)初始化一個Selector的結(jié)構(gòu)體出來。Selector的字符串內(nèi)容中,***是一個冒號“:”,和ObjC的寫法一樣的。冒號說 明方法有一個參數(shù)。***是UIControlEvents的枚舉類型。這里總于不用每次都寫的那么長了。
然后,實現(xiàn)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"這個字符串是要在界面中現(xiàn)實的。所以絕對不可以為空!
laContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError)檢查設(shè)備是不是可以用biometrics的方法驗證身份。就是看看能不能指紋解鎖。沒有硬件,或者有硬件沒設(shè)定好指紋的都是不可以驗證的。好的,如果已經(jīng)設(shè)定好了指紋,那么就可以解鎖了。
- laContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: errorReason, reply: {
- (success, error) in
- if success {
- println("succeed")
- }
- else{
- println("failed")
- }
- })
后面的replay參數(shù)是一個返回值為空的closure。這個closure的參數(shù)是bool和NSError!closure的一般形式是{(參數(shù)1, 參數(shù)2)->返回值類型 in //代碼}success返 回驗證結(jié)果,成功活失?。╰rue或false)。這時,根據(jù)驗證的成功或者失敗,替換掉println("succeed")或者 println("failed")語句,實現(xiàn)你需要實現(xiàn)的功能。比如,進入app的功能詳細頁等用Touch ID保護的信息。如果無法驗證,就跳轉(zhuǎn)到密碼驗證部分。這樣用戶在指紋驗證無法進行的情況下還可以通過輸入密碼進入到app的功能部分。
就到這里了。寫個項目試試吧!