前言
从最初做应用开始,我就密切关注用户的反馈和评论。有时他们的要求确实并不合理,但当大多数人提到一项功能时,就该我们做产品的人反思了。 私密保护功能是用户在评论中提到的,恰好像OneDay这样比较私密的内容确实可以增加这项功能。
指纹识别和面部识别虽然是两个很不相同的交互,但从开发的角度他们却只需要一套代码就可以搞定。在做之前我先解释下整个实现过程的重要环节:
原理图
1.我们需要一个数据来保存开关数据,在设置中心,用户根据喜好选择是否开启保护
2.一旦用户打开应用,通过判断是否保护来加载遮挡页面
3.在遮挡页面自动实现解锁过程,同时用户也可以点击后解锁
4.根据机型的不同,在设置中心需要显示不同的解锁名称
一、基础配置工作
实现指纹识别与面部识别,都是通过添加LocalAuthentication Framework来实现的。
导入LocalAuthentication Framework
之后在需要用到认证的页面,导入LocalAuthentication即可:
1
|
import LocalAuthentication
|
二、遮盖页创建与设置中心开关创建
在设置中心增加一栏开关,暂且叫做Touch ID,最后会进行标题文字的修复。 创建一个单独的遮盖页,只需要放置一句话及按钮即可,按钮将调用认证过程,文件为LockViewContrller.swift。
为了方便调用,给遮盖页设置了StoryBoard ID为LockController。
四、设置中心实现数据的修改
利用CoreData将开关的数据存储在ifProtect中,0表示开,1表示关。 设置数据的过程不会像其他数据那样直接改变,必须判断是否为用户本人进行开关。所以在SettingViewController.swift中,需要添加认证的相关函数。
1.先导入LocalAuthentication:
1
|
import LocalAuthentication
|
2.操作函数:
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
|
func touchID(){
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// 开始进入识别状态,以闭包形式返回结果。闭包的 success 是布尔值,代表识别成功与否。error 为错误信息。
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "请用指纹解锁" , reply: {success, error in
if success {
// 成功之后的逻辑, 通常使用多线程来实现跳转逻辑。
print( "解锁成功 success,允许设置" )
if self.appDelegate.mysetting.ifProtect == Int64( 1 ){
self.appDelegate.mysetting.ifProtect = Int64( 0 )
} else {
self.appDelegate.mysetting.ifProtect = Int64( 1 )
}
self.appDelegate.saveContext()
} else {
if let error = error as? NSError {
// 获取错误信息
let message = self.errorMessageForLAErrorCode(errorCode: error.code)
print(message)
}
//失败之后
print( "失败了" )
}
self.SettingTableView.reloadData()
})
}
}
|
当是用户本人且认证成功时,开关数据被改变;当不是用户本人或认证不成功,开关数据不会改变。 为了保持页面与数据统一,函数执行后我们需要刷新页面self.SettingTableView.reloadData()
。
3.获取错误情况:
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
35
36
37
|
func errorMessageForLAErrorCode(errorCode: Int) -> String {
var message = ""
switch errorCode {
case LAError.appCancel.rawValue:
message = "Authentication was cancelled by application"
case LAError.authenticationFailed.rawValue:
message = "The user failed to provide valid credentials"
case LAError.invalidContext.rawValue:
message = "The context is invalid"
case LAError.passcodeNotSet.rawValue:
message = "Passcode is not set on the device"
case LAError.systemCancel.rawValue:
message = "Authentication was cancelled by the system"
case LAError.touchIDLockout.rawValue:
message = "Too many failed attempts."
case LAError.touchIDNotAvailable.rawValue:
message = "TouchID is not available on the device"
// showPassWordInput()
case LAError.userCancel.rawValue:
message = "The user did cancel"
case LAError.userFallback.rawValue:
message = "The user chose to use the fallback"
default :
message = "Did not find error code on LAError object"
}
return message
}
|
五、首页加载遮盖页
来到首页HomeViewController,在viewDidLoad中加入下面代码,来判断每一次打开应用是否需要认证解锁。 如果不需要,首页可以正常显示; 如果需要,将直接跳转到LockController。
1
2
3
4
5
6
7
8
9
10
11
|
if self.appDelegate.mysetting.ifProtect == Int64(1){
print(self.appDelegate.mysetting.ifProtect)
print( "需要解锁" )
if let lockVC = storyboard?.instantiateViewController(withIdentifier: "LockController" ) as? LockViewController {
self.present(lockVC,animated: false ,completion: nil)
} else {
}
} else {
print( "不需要解锁" )
}
|
六、在遮盖页中实现认证
遮盖页LockController的背景通过虚化处理,可以到达遮盖的目的。同时拥有认证函数,当认证成功后页面自动消失返回首页。 因为需要认证过程,因此也需要三个核心步骤。
1.导入LocalAuthentication:
1
|
import LocalAuthentication
|
2.操作函数:
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
|
func touchID(){
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// 开始进入识别状态,以闭包形式返回结果。闭包的 success 是布尔值,代表识别成功与否。error 为错误信息。
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: "请用指纹解锁" , reply: {success, error in
if success {
// 成功之后的逻辑, 通常使用多线程来实现跳转逻辑。
print( "解锁成功 success" )
self.dismiss(animated: true , completion: nil)
} else {
if let error = error as? NSError {
// 获取错误信息
let message = self.errorMessageForLAErrorCode(errorCode: error.code)
print(message)
}
//失败之后
print( "失败了" )
}
})
}
}
|
认证过程成功后,页面会自动消失:self.dismiss(animated: true, completion: nil)
3.当用户进入页面时自动调取认证过程:
1
2
3
|
override func viewWillAppear(_ animated: Bool) {
touchID()
}
|
4.或者通过手动点击开始认证:
1
2
3
|
@IBAction func AuthenAction(_ sender: Any) {
touchID()
}
|
5.捕获错误跟设置页面一样。
七、根据屏幕尺寸修改开关标题
最后,我们来修复设置中心按钮的标题文字。当判断手机为iPhone X时,文字显示为“面部识别”或“Touch ID”;当不是iPhone X时,显示为“指纹识别”或“Touch ID”。这里我们用到了UIDevice来获取了屏幕的高度:
1
2
3
4
5
6
7
|
if UIDevice().userInterfaceIdiom == .phone && UIScreen.main.nativeBounds.height == 2436 {
cell.SwitchTitle.text = "Face ID"
cell.SwitchImage.image = UIImage(named: "btn_setting_faceid" )?.withRenderingMode(.alwaysTemplate)
} else {
cell.SwitchTitle.text = "Touch ID"
cell.SwitchImage.image = UIImage(named: "btn_setting_touchid" )?.withRenderingMode(.alwaysTemplate)
}
|
以上的过程便可实现私密保护,不过不会像系统解锁那样可以通过密码解锁。要实现密码解锁,还需要单独开发该功能。
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对服务器之家的支持。
原文链接:https://bjdehang.github.io/OneSwift/12.利用指纹识别或面部识别添加私密保护功能.html