首页 > 解决方案 > 自定义钥匙串警报操作

问题描述

我想知道是否可以自定义钥匙串警报?您可以在下面找到图片:

在此处输入图像描述

我想要达到的目标:

当使用 FaceID/TouchID 的身份验证失败并在显示的警报上方弹出时,我希望用户点击 Enter Passcode 并显示我的自定义应用程序密码 UI,而不是设备密码(系统 ui)。基本上,我想自定义回退操作。

上下文: 我知道 using 是可能的LAContext,但是由于我们可以绕过它的原因,我在实现它时感觉不舒服,所以我选择了 Keychain accessControlFlags。

快照代码,我目前拥有的:

func data(forAccount account: String, service: String, accessGroup: String?) throws -> Data? {
    guard let accessControl = createAccessControl(with: .userPresence) else { return nil }
    var query = self.query(forAccount: account, service: service, accessGroup: accessGroup)

    var authContext = LAContext()
    authContext.localizedFallbackTitle = "Enter Passcode"
    authContext.localizedCancelTitle = "Cancel"

    query[KeychainConstants.matchLimit] = KeychainConstants.matchLimitOne
    query[KeychainConstants.returnData] = kCFBooleanTrue
    query[KeychainConstants.authenticationContext] = authContext
    query[KeychainConstants.accessControl] = accessControl

    var result: AnyObject?
    let status = withUnsafeMutablePointer(to: &result) {
        securityItemManager.copyMatching(query, result: UnsafeMutablePointer($0))
    }

    if let error = error(fromStatus: status), error != .itemNotFound  {
        throw error
    }
    guard result != nil else { return nil }
    guard let resultData = result as? Data else { throw AccessError.invalidQueryResult }
    return resultData
}

标签: iosswiftkeychain

解决方案


您可以做的唯一自定义是更改对话框按钮标签。您可以使用以下方法执行此操作:

 let context = LAContext()

 context.localizedFallbackTitle = ""
 context.localizedCancelTitle = "Manual connection"

通过将localizedFallbackTitle属性设置为空字符串来删除回退按钮(输入密码)。

不幸的是,这个对话框没有“委托”类型的回调。您需要使用错误来管理用户交互。因此,LAError.userCancel当用户按下取消按钮时触发,当用户按下LAError.userFallback后备按钮时触发。

这是一个例子:

let context = LAContext()
context.localizedFallbackTitle = "Facebook"
context.localizedCancelTitle = "Web Connection"

[...]

context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics,
                       localizedReason: "My reason") { (success, errorOrNil) in

if let error = errorOrNil {

   if success {

      // The evaluation succeeded

   } else {

      if let error = errorOrNil {

         switch error {
             case .userCancel: 

                 // Execute the custom actions you want to do. Here it would be
                 // to start a web login process.
                 self.webLogin()

             case .userFallback: 

                self.fabebookAuthentication() 

             default: 
                 // Other error thrown by the framework.
         }
      }
   }
 }

推荐阅读