打开成长之旅!这是我参与「日新方案 12 月更文应战」的第2天,点击检查活动概略

好久不见,我是 new_cheng。

苹果在 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 解锁 的开关设置,先来简略的编写这个页面。

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

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 权限才华够运用解锁哦")
}

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

请用真机运行。

点击 【去打开】 后,会直接跳转到系统设置中对应 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 解锁
          authenticateFaceId() // 还是先检查系统是否授权了脸庞 ID
          if !isGoOpenAuth {
            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())
  }
}

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

在 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 或许指纹辨认的运用。合理的运用苹果供给的功用,来进步你应用的用户体会吧。

这是 SwiftUI 开发之旅专栏的文章,是 swiftui 开发学习的经验总结及实用技巧同享,欢迎注重该专栏,会坚持输出。一起欢迎注重我的个人群众号 @JSHub:供给最新的开发信息速报,优质的技术干货引荐。或是检查我的个人博客:Devcursor。

点赞:假设有收成和帮忙,请点个赞支撑一下!

保藏:欢迎保藏文章,随时检查!

评论:欢迎评论交流学习,共同进步!