Touch ID和Keychain的简单组合使用

Touch ID是苹果生物指纹授权技术,首先是在iPhone 5s上被看到。Touch ID嵌入home建非常方便使用。一旦你的手指触摸home建,Touch ID传感器将立马读取你的指纹,通过分析,确定你是否可以访问iPhone。安全和私有是Touch ID传感器的最大两个关注点。根据苹果,你的设备不能够存储任意包含你的指纹的图片。通过扫描指纹转换到数学显示并且进行加密存储到安全的芯片当中。

第一次公开是iOS7,我们能够使用Touch ID来解锁我们的iPhone,并且可以授权购物,付款等各种功能。iOS7的时候,苹果并不允许开发者在自己的APP中使用APIs来实现Touch ID的授权操作。随着新版本的发布,苹果拥有了大量的新技术和框架,iOS8使用了新技术,然后公开了Touch ID的API可以进行使用。使用Touch ID可以取代使用密码,要使用Touch ID需要使用新的框架,为Local Authentication.该框架提供了方法进行授权操作,并且提供了许多机会访问APP的敏感信息。

Local Authentication框架的核心是LAContext类,提供了两个方法:

canEvaluatePolicy(_:error:)该方法进行评估给与的授权策略是否能够进行授权,在进行写入的时候,DeviceOwnerAuthenticationWithBiometrics是唯一的策略。如果方法返回的是正数,意味着设备支持Touch ID授权。另一方面,如果返回是负数,该设备可能没有Touch ID传感器或者用户并不能够使用指纹授权特性。

evaluatePolicy(_:localizedReason:reply:)当方法被调用的时候,它将呈现授权提示框,请求指纹扫描。授权是异步执行的,当授权完成,reply block将被调用并且回调授权结果。如果授权失败,将返回LAError对象说明出错的原因。

上面理论部分内容已经足够了,现在开始来玩玩代码:原文地址内容

功能描述:运行程序得到一个授权界面,通过授权进入文本编辑界面,如果之前使用过KeychainWrapper存储过输入的内容,那么本次授权之后,会直接显示上次显示的内容,如果上次没有存储过内容,那么需要新输入内容进行存储,然后再次授权进行验证是否存储成功,效果如下图:



具体Demo如下:对于SwiftKeychainWrapper的解释和使用,可以看这里,本文是使用这里的。

import LocalAuthentication
import UIKit

class ViewController: UIViewController {
	@IBOutlet weak var secret: UITextView!

	override func viewDidLoad() {
		super.viewDidLoad()

		title = "Nothing to see here"
        //添加相应的键盘通知
		let notificationCenter = NotificationCenter.default
		notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: Notification.Name.UIKeyboardWillHide, object: nil)
		notificationCenter.addObserver(self, selector: #selector(adjustForKeyboard), name: Notification.Name.UIKeyboardWillChangeFrame, object: nil)
        //当APP不在活跃,即在前台运行,或当设备被锁,或回到home页,或切换到多任务模式,或进入后台都除触发通知,并保存当前输入的数据,下次进行直接授权查看之前保存的数据
		notificationCenter.addObserver(self, selector: #selector(saveSecretMessage), name: Notification.Name.UIApplicationWillResignActive, object: nil)
	}
    
    //根据键盘的显示和消失调节textview的位置
	func adjustForKeyboard(notification: Notification) {
		let userInfo = notification.userInfo!

		let keyboardScreenEndFrame = (userInfo[UIKeyboardFrameEndUserInfoKey] as! NSValue).cgRectValue
		let keyboardViewEndFrame = view.convert(keyboardScreenEndFrame, from: view.window)

		if notification.name == NSNotification.Name.UIKeyboardWillHide {
			secret.contentInset = UIEdgeInsets.zero
		} else {
			secret.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: keyboardViewEndFrame.height, right: 0)
		}

		secret.scrollIndicatorInsets = secret.contentInset
		let selectedRange = secret.selectedRange
		secret.scrollRangeToVisible(selectedRange)
	}

    //点击授权按钮
	@IBAction func authenticateTapped(_ sender: AnyObject) {
		let context = LAContext()
		var error: NSError?

        //询问是否可以进行授权,返回True表示支持. Touch ID是Local Authentication framework的一部分,我们的代码需要做3件事:1)确认设备是否支持生物识别授权 2)如果支持,请求 Touch ID开始确认,并且给与一个字符串,字符串说明我们使用 Touch ID的原因 3)如果我们在进行 Touch ID授权之后,返回成功表示设备持有者能够解锁APP,是否显示错误信息。
		if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
			let reason = "Identify yourself!"

            //注意:闭包中使用无主引用防止循环引用
			context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) {
				[unowned self] (success, authenticationError) in

                //这里需要注意:当我们被告知授权是否成功,当前线程不一定是主线程,所以我们要确保回到主线程更新用户界面。
				DispatchQueue.main.async {
					if success {
                        //授权成功,显示保存的信息
						self.unlockSecretMessage()
					} else {
                        //授权失败,提示出错
						let ac = UIAlertController(title: "Authentication failed", message: "Your fingerprint could not be verified; please try again.", preferredStyle: .alert)
						ac.addAction(UIAlertAction(title: "OK", style: .default))
						self.present(ac, animated: true)
					}
				}
			}
		} else {
            var errorMessage:String = ""
            if let error = error {
                switch error.code {
                case LAError.authenticationFailed.rawValue:
                    errorMessage = "Authentication failed because the fingerprint does not match up with those enrolled."
                case LAError.passcodeNotSet.rawValue:
                    errorMessage = "Passcode not set"
                case LAError.systemCancel.rawValue:
                    errorMessage = "Authentication was canceled by system"
                case LAError.userCancel.rawValue:
                    errorMessage = "Authentication was canceled by the user"
                case LAError.touchIDNotEnrolled.rawValue:
                    errorMessage = "Authentication could not start because Touch ID has no enrolled fingers."
                case LAError.touchIDNotAvailable.rawValue:
                    errorMessage = "Authentication could not start because Touch ID is not available."
                case LAError.userFallback.rawValue:
                    errorMessage = "User tapped the fallback button (Enter Password)."
                default:
                    errorMessage = error.localizedDescription
                }
            }
			let ac = UIAlertController(title: "Touch ID not available", message: errorMessage, preferredStyle: .alert)
			ac.addAction(UIAlertAction(title: "OK", style: .default))
			self.present(ac, animated: true)
		}
	}

    //加载秘密信息显示到textview上
	func unlockSecretMessage() {
		secret.isHidden = false
		title = "Secret stuff!"
        //获取存储的信息
		if let text = KeychainWrapper.standardKeychainAccess().string(forKey: "SecretMessage") {
			secret.text = text
		}
	}

    //保持textview中输入的信息到Keychain
	func saveSecretMessage() {
		if !secret.isHidden {
            //存储textview中的信息
			KeychainWrapper.standardKeychainAccess().setString(secret.text, forKey: "SecretMessage")
            //去除textview
			secret.resignFirstResponder()
            //隐藏textview
			secret.isHidden = true
			title = "Nothing to see here"
		}
	}
}




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值