首先,我对 swift 非常陌生,它不是我的主要语言。我很难理解并发构造,有些还不可用(直到 macOS 12 发布)。
所以我希望命令行应用程序使用笔记本电脑的 touchId 来访问一些数据。我发现了很多电话的例子LAContext.evaluatePolicy
。然而,它们似乎都与 GUI 应用程序相关(在 macOS 或 iOS 中)。
我的问题是我正在开发一个终端应用程序,并且在主线程完成时在私有队列evaluatePolicy
上进行评估,而没有留出时间实际显示身份验证对话框。
我试图创建一个非常简单的复制器,纯粹是快速的。(但我的终端应用程序在 C 中有一些调用 swift 方法的代码)。
import LocalAuthentication
@_cdecl("authenticate")
public func authenticateUser() {
let context = LAContext()
context.localizedFallbackTitle = "Please use your password"
context.localizedCancelTitle = "Abort"
var authorizationError: NSError?
let permissions = context.canEvaluatePolicy(
LAPolicy.deviceOwnerAuthentication, // TouchId or passcode
error: &authorizationError
)
if permissions {
let biometry = context.biometryType
if (biometry != LABiometryType.touchID) {
print("TouchID not available")
return
}
let reason = "Identify yourself!"
print(reason)
context.evaluatePolicy(
LAPolicy.deviceOwnerAuthentication,
localizedReason: reason
) { (success: Bool, error: Error?) -> Void in
if success {
print(" You may enter")
} else {
print(" Authentication failed")
print(error?.localizedDescription ?? "Failed to authenticate")
}
}
// <-------- block here
} else {
let ac = "Touch ID not available, Or Your device is not configured for Touch ID."
print(ac)
}
}
authenticateUser()
在此代码段中,我希望阻止代码以等待evaluatePolicy
结果。通过其回复完成处理程序或其他方式。
我尝试过使用DispatchQueue.main.async
,但这不起作用,所以我最终没有正确使用。我也尝试过使用等待/异步,但swiftc
告诉我这些在我的系统上不可用(concurrency is only available in macOS 12.0.0 or newer
)。
这可以这样编译和执行:
$ swiftc main.swift
$ ./main
Identify yourself!
提前感谢您提供指导以完成这项工作。
一些版本
$ swiftc --version
Apple Swift version 5.5 (swiftlang-1300.0.31.1 clang-1300.0.29.1)
Target: x86_64-apple-darwin20.6.0
$ sw_vers
ProductName: macOS
ProductVersion: 11.6
BuildVersion: 20G165