iOS 8 中如何用 Swift 實(shí)現(xiàn) Touch ID 驗(yàn)證
iOS8開(kāi)放了很多API,包括HomeKit、HealthKit什么的。我們這里要說(shuō)的是其中之一的Touch ID驗(yàn)證。
以前用app保護(hù)用戶(hù)的隱私內(nèi)容,只能設(shè)定和輸入密碼。眼看著只能是iPhone本身用Touch ID方便酷炫的解鎖而自己的app不能。實(shí)在讓人捉急。現(xiàn)在咱也可以酷炫一把了。當(dāng)用戶(hù)打開(kāi)使用了Touch ID認(rèn)證的app查看什么內(nèi)容的時(shí)候就只能是把手指放在Home鍵上去驗(yàn)證身份。在app中驗(yàn)證的指紋就是用戶(hù)在手機(jī)里的指紋。是的,你的app無(wú)需用戶(hù) 再輸入一次驗(yàn)證用的指紋了。所以使用起來(lái)還是很方便的。不過(guò)你要做好其他的準(zhǔn)備。就像iPhone解鎖少不了密碼輸入一樣。用戶(hù)如果沒(méi)有開(kāi)啟Touch ID咱的app也不能扒瞎不是?
如題所述,這個(gè)項(xiàng)目使用Swift來(lái)實(shí)現(xiàn)的。如果你的swift不熟的話,需要略微補(bǔ)補(bǔ)腦哦。
說(shuō)了這么多,看看效果吧

看到了吧。只要把大拇指放在Home鍵上就會(huì)解鎖了。
界面布局是這樣的:

這里是通過(guò)點(diǎn)擊按鈕觸發(fā)驗(yàn)證的。點(diǎn)了Authenticate按鈕之后彈出***張圖的驗(yàn)證提示。
好啦,進(jìn)入正題。
首先創(chuàng)建一個(gè)項(xiàng)目。名字啊什么的就隨你的便了都可以。但是編程語(yǔ)言,這里需要選擇Swift。既然xcode6.0.1已經(jīng)號(hào)稱(chēng)提供了對(duì)swift 的全面支持。那我們就直接上swift了。實(shí)在不行還可以通過(guò)蘋(píng)果提供的機(jī)制調(diào)用已有的ObjC代碼。總之五個(gè)字:這都不是事。而且swfit本來(lái)也可以 省很多的代碼量。項(xiàng)目的其他的地方保持默認(rèn)選擇就可以。也就是我們省點(diǎn)事,直接用storyboard就好了。雖然其實(shí)沒(méi)有什么界面元素可以省略了。。。
在創(chuàng)建好的項(xiàng)目里,選擇Build Phases。把LocalAuthentication的framework引入項(xiàng)目。到這里項(xiàng)目的設(shè)置就可以了。
在代碼中import引入的framework。
- import LocalAuthentication
接下來(lái)創(chuàng)建一個(gè)按鈕:
- 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)建一個(gè)和系統(tǒng)同類(lèi)型的按鈕。UIButton.buttonWithType(UIButtonType.System)返回的是一個(gè)AnyObject類(lèi)型的對(duì)象,所以需要強(qiáng)制類(lèi)型轉(zhuǎn)換成UIButon的。AnyObject和Any這兩個(gè)類(lèi)型會(huì)經(jīng)常遇到。主要是為了和ObjC之前的代碼想兼容。所以也會(huì)經(jīng)常的用is或者as操作符檢測(cè)和強(qiáng)制類(lèi)型轉(zhuǎn)換。
- AnyObject是指任何一個(gè)class類(lèi)型的實(shí)例
- Any是指任何一個(gè)類(lèi)型的實(shí)例
比如,AnyObject數(shù)組可以存放任意某個(gè)class類(lèi)型的實(shí)例。這些實(shí)例都是class類(lèi)型,而且是同一個(gè)類(lèi)型的。Any的數(shù)組則可以放任意類(lèi)型的實(shí)例,而且這些數(shù)組成員的類(lèi)型不一定是一樣的。
創(chuàng)建UIButton的代碼和之前用OC的方式?jīng)]有什么太大的區(qū)別。只不過(guò)換成了swift的語(yǔ)法。有了按鈕以后,也就該設(shè)定按鈕點(diǎn)擊事件的處理方法了。還記得不addTarget:
- authButton.addTarget(self, action: Selector("addPassAction:"), forControlEvents: UIControlEvents.TouchUpInside)
先看看addTarget的聲明:func addTarget(target: AnyObject?, action: Selector, forControlEvents controlEvents: UIControlEvents) 對(duì) 應(yīng)在方法的調(diào)用中可以看到self就是AnyObject的target,不用多說(shuō)什么了。后面的action是一個(gè)Selector的結(jié)構(gòu)體 (struct)。我們?cè)谡{(diào)用的時(shí)候初始化了一個(gè)Selector的結(jié)構(gòu)體。這個(gè)參數(shù)也可以直接給出action的字符串,而不用初始化Selector 這個(gè)結(jié)構(gòu)體。這里涉及到了一個(gè)類(lèi)型自動(dòng)轉(zhuǎn)換的知識(shí)點(diǎn)。Selector的構(gòu)造函數(shù)需要提供一個(gè)字符串作為參數(shù),所以如果直接給出字符串的時(shí)候編譯器會(huì)直接 把這個(gè)字符串作為參數(shù)初始化一個(gè)Selector的結(jié)構(gòu)體出來(lái)。Selector的字符串內(nèi)容中,***是一個(gè)冒號(hào)“:”,和ObjC的寫(xiě)法一樣的。冒號(hào)說(shuō) 明方法有一個(gè)參數(shù)。***是UIControlEvents的枚舉類(lèi)型。這里總于不用每次都寫(xiě)的那么長(zhǎng)了。
然后,實(shí)現(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驗(yàn)證的功能了。var laContext = LAContext()用到了類(lèi)型推斷。給變量初始化的實(shí)例是什么類(lèi)型的,這個(gè)變量就自動(dòng)推斷為是那個(gè)類(lèi)型。var authError : NSError? 類(lèi) 型推斷和optional value。optional value就是在類(lèi)型的后面加了一個(gè)問(wèn)號(hào)。表示這個(gè)值可以是某個(gè)實(shí)例也可以是nil。注意:swift的nil和ObjC的nil是兩回事。ObjC的 nil是引用類(lèi)型的一個(gè)空值。swift的nil就是說(shuō)此變量沒(méi)有值,是不是引用類(lèi)型都可以。var errorReason = "keep things secret"這個(gè)字符串是要在界面中現(xiàn)實(shí)的。所以絕對(duì)不可以為空!
laContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error: &authError)檢查設(shè)備是不是可以用biometrics的方法驗(yàn)證身份。就是看看能不能指紋解鎖。沒(méi)有硬件,或者有硬件沒(méi)設(shè)定好指紋的都是不可以驗(yàn)證的。好的,如果已經(jīng)設(shè)定好了指紋,那么就可以解鎖了。
- laContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: errorReason, reply: {
- (success, error) in
- if success {
- println("succeed")
- }
- else{
- println("failed")
- }
- })
后面的replay參數(shù)是一個(gè)返回值為空的closure。這個(gè)closure的參數(shù)是bool和NSError!closure的一般形式是{(參數(shù)1, 參數(shù)2)->返回值類(lèi)型 in //代碼}success返 回驗(yàn)證結(jié)果,成功活失敗(true或false)。這時(shí),根據(jù)驗(yàn)證的成功或者失敗,替換掉println("succeed")或者 println("failed")語(yǔ)句,實(shí)現(xiàn)你需要實(shí)現(xiàn)的功能。比如,進(jìn)入app的功能詳細(xì)頁(yè)等用Touch ID保護(hù)的信息。如果無(wú)法驗(yàn)證,就跳轉(zhuǎn)到密碼驗(yàn)證部分。這樣用戶(hù)在指紋驗(yàn)證無(wú)法進(jìn)行的情況下還可以通過(guò)輸入密碼進(jìn)入到app的功能部分。
就到這里了。寫(xiě)個(gè)項(xiàng)目試試吧!






















