我对canEvaluatePolicy函数有问题。
我像这样声明了这个函数:
func canEvaluatePolicy(policy: LAPolicy) {
do {
try authenticationObject.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics)
} catch let error as NSError {
print("Error: (error.domain)")
}
}
但是当我想像这样使用它时:
if authenticationObject.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics) {
我有一个错误:
Error: Cannot invoke 'canEvaluatePolicy' with an argument list of type '(LAPolicy)'
谢谢
首先,假设authenticationObject
是一个LAContext
,你不能在不处理它可能抛出的错误的情况下调用它的canEvaluatePolicy
方法。确保错误得到处理*是throws
方法的全部意义所在。
其次,当返回带有NSError
out-parameter 的 BOOL
的 ObjC API 导入到 Swift 中时,它们会丢失布尔返回类型 — 它们变成了没有返回类型的抛出函数(嗯,Void
作为返回类型......同样的事情)。这是因为,对于这些函数,假设false
返回总是带有错误,而true
返回总是指示没有错误。
因此,您不需要测试(缺少)返回值 - 相反,您需要这样的东西:
do {
try authenticationObject.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics)
// if you get here, "can evaluate" is true
// feel free to call evaluatePolicy or whatever
} catch {
print(error) // or present an alert, etc.
}
或者,将其包装在您自己的本地函数中:
func canEvaluate() -> Bool {
do {
try authenticationObject.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics)
return true
} catch {
print(error) // or present an alert, etc.
return false
}
}
在实际用法中,您可能希望在catch
子句上进行一些模式匹配 - 某些LAError
值是您可能想要吞下的内容(如果用户按 Cancel,则无需显示另一个警报说他们按下了 Cancel),而其他值则是您想要与之交互的内容。
* 当然,"处理"错误可以像选择忽略它或选择中止一样简单,尽管其中一些选择可能会损害您的用户体验。但这是你的选择,这是这里重要的部分......就像 Swift 1 引入了必须考虑可选性作为确保你编写的代码安全的一种方式的想法一样,Swift 2 引入了必须考虑可能的错误的想法。