阅读 129

SwiftUI 开发之旅:Face ID 的使用技巧

苹果在 iPhone X 上发布 Face ID 后,这一功能基本已经成为 iPhone 系列的标配了;在 IOS 开发中也会经常用到 Face ID。

以下简称 面容 ID。

在使用面容 ID 之前,我们先来看看,它的常用场景:

  • APP 解锁

  • 支付

这里我们以解锁的场景为例,看看如何使用面容 ID:

从 App 解锁的使用角度来看,用户会有以下相关操作:

  1. 首先用户要去 app 的设置页面开启 faceid 解锁选项。

  2. 开启面容 ID 解锁时需要检查 app 是否拥有面容id的授权。

  3. 没有面容id的授权时,弹窗提醒,用户点击确认后需要跳转去系统设置页面给app开启面容id授权。

  4. 授权完成后,用户可以打开 faceid 解锁选项。

  5. 重新进入app的时候,显示一个解锁页面,调用面容 ID解锁,如果用户取消了解锁,那就无法显示 app 的其他内容

以上是涉及到面容 ID 解锁的一个基本业务流程,下面我们来完成具体实现。

面容 ID 解锁的开关设置

我们先要在 app 的设置页面里面加入一个 Face ID 解锁 的开关设置,先来简单的编写这个页面。

image.png

Setting.swift:

struct Settings: View {     @EnvironmentObject var appSetting: AppSetting          @State private var isOpenFaceIdLock = false     var body: some View {         ScrollView {             VStack(alignment: .leading) {                 // ...                 HStack {                     Toggle(isOn: $isOpenFaceIdLock) {                         HStack {                             Text("????")                                 .font(.system(size: 16))                             Text("FaceID 解锁")                                 .font(.body)                                 .fontWeight(.medium)                                 .foregroundColor(.gray)                             Spacer()                             Image(systemName: "chevron.right")                                 .foregroundColor(Color.gray)                                 .font(.system(size: 14))                         }                     }                     .onChange(of: isOpenFaceIdLock) { value in                         // 将用户设置保存起来                         appSetting.isOpenFaceIdLock = value                     }                 }             }         }          .onAppear {             // 初始化时,使用 AppSetting 的值             self.isOpenFaceIdLock = UserDefaults.standard.bool(forKey: "isOpenFaceIdLock")         }     } } 复制代码

一个简单的设置页面就完成了,在这里我们还引入了 AppSetting,用于持久化存储用户的设置,上一次我们在 SwiftUI 开发之旅:适配深色模式 中用到了它。现在,我们会继续在原有的基础上往 AppSetting 中添加关于面容 ID 的内容。

对 AppSetting 有不了解的可以点击适配深色模式的链接前往查看。

我们要在 AppSetting 中加入一个新的字段 isOpenFaceIdLock,用于存储 面容 ID 解锁的设置:

// 是否开启 FaceId 解锁 @Published var isOpenFaceIdLock: Bool = UserDefaults.standard.bool(forKey: "isOpenFaceIdLock") {     didSet {         // 监听数据变化,持久化数据         UserDefaults.standard.set(self.isOpenFaceIdLock, forKey: "isOpenFaceIdLock")     }  } 复制代码

检查是否授权使用面容 ID

面容 ID 解锁默认是不开启的,当用户开启该设置的时候,我们要先检查我们的 App 是否被系统授权使用 面容 ID 解锁。

在 Setting.swift 中新增 authenticate 函数和用于提示用户需要开启授权的控制变量 isGoOpenAuth

  1. 先引入 LocalAuthentication 依赖:

import LocalAuthentication 复制代码

  1. 新增函数和变量:

// 是否需要前往设置页面开启权限 @State private var isGoOpenAuth: Bool = false // 先检测是否开启面容id授权 func authenticate() {     let context = LAContext()     var error: NSError?     // 检查是否可以进行生物特征识别     if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {         self.isGoOpenAuth = false     } else {         // 没有生物指纹识别功能         if (error?.code == -6) {             self.isGoOpenAuth = true             print("没有生物指纹识别功能")         }     } } 复制代码

  1. 当系统没有授权使用面容 ID 时,提醒用户前往开启授权

ScrollView {     // ... } .alert("", isPresented: $isGoOpenAuth) {     Button(role: .cancel) {         self.isGoOpenAuth = false         self.isOpenFaceIdLock = false     } label: {         Text("取消")     }     Button() {        // 前往设置页面进行授权        guard let url = URL(string: UIApplication.openSettingsURLString) **else** {            return        }        if #available(iOS 10.0, *) {            UIApplication.shared.open(url, options: [:], completionHandler: nil)        } else {            UIApplication.shared.openURL(url)        }     } label: {         Text("去开启")     } } message: {     Text("开启面容 ID 权限才能够使用解锁哦") } 复制代码

2721669086717_.pic.jpg

请用真机运行。

点击 【去开启】 后,会直接跳转到系统设置中对应 App 的设置页面。

到这里,一个检查授权面容 ID 和持久化用户设置的功能就完成了。

面容 ID 的解锁页面

在用面容 ID 解锁前,为了用户信息安全,是不能显示 App 内的页面内容的。这时候我们就需要一个专用与解锁的页面,当没有进行解锁的时候, App 会一直显示该页面直到解锁成功。

FaceIdLock.swift:

import SwiftUI struct FaceIdLock: View {     @EnvironmentObject var appSetting: AppSetting     // 是否需要前往设置页面开启权限     @State private var isGoOpenAuth: Bool = false     // 先检测是否开启面容id授权     func authenticateFaceId() {         let context = LAContext()         var error: NSError?         // 检查是否可以进行生物特征识别         if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {            self.isGoOpenAuth = false         } else {             // 没有生物指纹识别功能             if (error?.code == -6) {                 self.isGoOpenAuth = **true**                 print("没有生物指纹识别功能")             }         }     }     var body: some View {         ZStack {             Color("mainBg").edgesIgnoringSafeArea(.all)             VStack {                 Button(action: {                     // 如果用户不小心取消了解锁,需要提供一个点击重新解锁的方式:当用户点击时,调用面容 ID 解锁                     appSetting.authenticate()                 }, label: {                     VStack {                         Image(systemName: "faceid")                             .foregroundColor(Color.blue)                             .font(.system(size: 54))                             .padding()                         Text("点击进行面容 ID 登录")                             .foregroundColor(Color.textColor)                     }                 })             }         }         .alert("", isPresented: $isGoOpenAuth) {             Button(role: .cancel) {                 self.isGoOpenAuth = **false**             } label: {                 Text("取消")             }             Button() {                // 前往设置页面进行授权                guard let url = URL(string: UIApplication.openSettingsURLString) else {                    **return**                }                if #available(iOS 10.0, *) {                    UIApplication.shared.open(url, options: [:], completionHandler: nil)                } else {                    UIApplication.shared.openURL(url)                }             } label: {                 Text("去开启")             }         } message: {             Text("开启面容 ID 权限才能够使用解锁哦")         }         .ignoresSafeArea(edges: .top)         .onAppear {             // 初始化显示时,先判断是否授权了faceid             authenticateFaceId()             if !isGoOpenAuth {                 appSetting.authenticate()             }         }     } } struct FaceIdLock_Previews: PreviewProvider {     static var previews: some View {         FaceIdLock()             .environmentObject(AppSetting())     } } 复制代码

image.png

在 FaceIdLock 页面,我们同样需要检测是否授权了面容 ID 权限,不然,App 会一直停留在该页面,且无法调起面容 ID 进行解锁。

接着在入口页面 ContentView.swift 中添加一个条件判断:

struct ContentView: View {     @EnvironmentObject var appSetting: AppSetting     var body: some View {         VStack {             if appSetting.isOpenFaceIdLock && !appSetting.isUnlocked {                 FaceIdLock()                     .frame(maxHeight: .infinity)             } else {             // ...             }         }     } } 复制代码

调用面容 ID API

接下来我们需要完成在 FaceIdLock.swift 中解锁时调用的 AppSetting 的 authenticate 函数。

AppSetting.swift:

import LocalAuthentication class AppSetting: ObservableObject {     // 是否已解锁,只有在使用 faceid 的前提下才能使用该变量,用于判断后面的操作是否能进行     @Published var isUnlocked: Bool = false     func authenticate() {         let context = LAContext()         var error: NSError?         // 检查是否可以进行生物特征识别         if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {             // 如果可以,执行识别             let reason = "开启面容 ID 权限才能够使用解锁哦"             context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason) { success, authenticationError **in**                 // 鉴权完成                 DispatchQueue.main.async {                     if success {                         // 鉴权成功                         self.isUnlocked = true                     } else {                         // 鉴权失败                         self.isUnlocked = false                     }                 }             }         } else {             // 没有生物指纹识别功能             if (error?.code == -6) {                 print("没有生物指纹识别功能")             }         }     } } 复制代码

到这里,我们已经完成了一个比较完整的使用面容 ID 解锁的功能了????

总结

我们通过实操,完成了一个面容 ID 的使用功能,完整还原了使用面容 ID 的的业务流程。除了自己编写代码来使用面容 ID,你还可以通过诸如 BiometricAuthentication 的第三方库来完成面容 ID 或者指纹识别的使用。合理的运用苹果提供的功能,来提升你应用的用户体验吧。


作者:new_cheng
链接:https://juejin.cn/post/7168739744246038565

文章分类
百科问答
版权声明:本站是系统测试站点,无实际运营。本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 XXXXXXo@163.com 举报,一经查实,本站将立刻删除。
相关推荐