实践 - Touch ID 解锁功能

导语

iOS 8 引入了 Touch ID 认证的方式来解决输入密码的麻烦操作,Swift 最低需要 iOS 8,因此本文会用 Swift 来实现 Touch ID 功能

环境

macOS Sierra 10.12.4
Xcode 8.3.1
Swift 3.0
iPhone 6S 10.1.1

Touch ID 需要硬件支持

LocalAuthentication.framework

Touch ID 认证依赖的框架,引入即可

LAContext

Touch ID 认证的上下文对象

有两个方法

能不能?

1
open func canEvaluatePolicy(_ policy: LAPolicy, error: NSErrorPointer) -> Bool

LAPolicy

1
2
3
4
5
6
7
8
public enum LAPolicy : Int {
/// Device owner was authenticated using a biometric method (Touch ID).
@available(iOS 8.0, *)
case deviceOwnerAuthenticationWithBiometrics

/// Device owner was authenticated by Touch ID or device passcode.
@available(iOS 9.0, *)
case deviceOwnerAuthentication

具体用那种策略去验证。

NSErrorPointer

1
public typealias NSErrorPointer = AutoreleasingUnsafeMutablePointer<NSError?>?

流程(显示什么,结果如何?)

1
open func evaluatePolicy(_ policy: LAPolicy, localizedReason: String, reply: @escaping (Bool, Error?) -> Swift.Void)

localizedReason

要求 Touch ID 验证的原因

reply

返回的结果后的回调

LAError

失败的原因有

  • 认证失败(比如用了未被认证的手指)
  • 用户取消
  • 用户取消选择了输入密码
  • 系统取消(比如另一个程序切换至前台)
  • 未设置密码
  • 设备不支持
  • 未设置 Touch ID (手指没设置)

iOS 9 上又添加了 3 种情况

  • 失败次数过多
  • 被取消 ( 上一次认证过程还未结束 )
  • LAContext 上下文对象有不合法

具体详情可以查看 LAError 枚举的定义

Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
func authenticateUser() {
// Get the local authentication context.
let context = LAContext()

// Declare a NSError variable.
var error: NSError?

// Set the reason string that will appear on the authentication alert.
let reasonString = "请画押🐾"

if context.canEvaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, error: &error) {
_ = [context .evaluatePolicy(LAPolicy.deviceOwnerAuthenticationWithBiometrics, localizedReason: reasonString, reply: { (success: Bool, evalPolicyError: Error?) -> Swift.Void in

if success {
print("Authentication success")
} else{

let err : LAError = LAError(_nsError: evalPolicyError! as NSError)
switch err.code.rawValue {
case LAError.systemCancel.rawValue:
print("Authentication was cancelled by the system")
case LAError.userCancel.rawValue:
print("Authentication was cancelled by the user")
case LAError.userFallback.rawValue:
print("User selected to enter custom password")
default:
print("Authentication failed")
break
}
}

} )]
}
}

Demo

总结

  Touch ID 功能的设计其实比较直观,实现也挺容易的,遇到的干扰主要是 Swift 由于版本迭代语法上的差异。

参考

  1. Working with Touch ID API in iOS 8 SDK
  2. What’s New in iOS 8.0
  3. Touch ID
  4. Xcode 8 / Swift 3: “Expression of type UIViewController? is unused” warning