我正在创建一个新应用程序,我想放入一个隐藏文件夹。可通过面部ID/Touch ID访问。我已经实现了代码,但是当我运行应用程序并使用Face ID时。应用程序崩溃并显示错误"NSInternalInconsistencyException">
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Modifications to the layout engine must not be performed from a background thread after it has been accessed from the main thread.
在我的视图控制器中,我已将视图设置为:
override func viewDidLoad() {
super.viewDidLoad()
let cornerRadius : CGFloat = 10.0
containerView.layer.cornerRadius = cornerRadius
tableView.clipsToBounds = true
tableView.layer.cornerRadius = 10.0
// 1
let context = LAContext()
var error: NSError?
// 2
// check if Touch ID is available
if context.canEvaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, error: &error) {
// 3
let reason = "Authenticate with Biometrics"
context.evaluatePolicy(.deviceOwnerAuthenticationWithBiometrics, localizedReason: reason, reply: {(success, error) in
// 4
if success {
self.showAlertController("Biometrics Authentication Succeeded")
} else {
self.showAlertController("Biometrics Authentication Failed")
}
})
}
// 5
else {
showAlertController("Biometrics not available")
}
}
我希望面容 ID/触控 ID 按预期工作,并且在验证后不会崩溃。
您正在后台线程上进行 UI 调用(显示警报(,因此您遇到此问题。
更改以下内容
if success {
self.showAlertController("Biometrics Authentication Succeeded")
} else {
self.showAlertController("Biometrics Authentication Failed")
}
自
DispatchQueue.main.async {
if success {
self.showAlertController("Biometrics Authentication Succeeded")
} else {
self.showAlertController("Biometrics Authentication Failed")
}
}
如果要更新 UI 部分,请记住始终使用 DispatchQueue.main.async 来运行这些任务。 UI 更改必须在主线程中运行。
如何使用 Swift 4 添加 FaceID/TouchID
您还可以查看使用面容 ID 或触控 ID 将用户登录到您的应用 - Apple 文档 如果您向下滚动到Evaluate a Policy
部分。
错误非常明显:
从主线程访问布局引擎后,不得从后台线程执行对布局引擎的修改。
您无法从主线程以外的任何线程编辑 UI,就像您尝试对evaluatePolicy
回调所做的那样。应将 UI 修改代码放在对DispatchQueue.main.sync
的调用中