iOS代码执行错误
我正试图根据TouchID尝试登录的结果更改标签上的文本,但是有一个延迟。当我尝试导航到另一个视图(如此处的视频显示)时,也会发生同样的情况 假设我有一个开关来处理不同的登录错误可能性,在每种情况下,如果我尝试更改标签,就会出现延迟,如果我使用这些情况来更改字符串变量的内容,并尝试将此变量的内容分配给函数末尾的标签,断点显示将变量分配给标签的行在评估登录尝试的块之前执行,代码如下:iOS代码执行错误,ios,concurrency,swift,Ios,Concurrency,Swift,我正试图根据TouchID尝试登录的结果更改标签上的文本,但是有一个延迟。当我尝试导航到另一个视图(如此处的视频显示)时,也会发生同样的情况 假设我有一个开关来处理不同的登录错误可能性,在每种情况下,如果我尝试更改标签,就会出现延迟,如果我使用这些情况来更改字符串变量的内容,并尝试将此变量的内容分配给函数末尾的标签,断点显示将变量分配给标签的行在评估登录尝试的块之前执行,代码如下: func requestUserAuthentication() { var myContext:LAC
func requestUserAuthentication() {
var myContext:LAContext = LAContext()
var authError:NSError?
var myLocalizedRasonMessage = "Please authenticate using your fingerprint"
if (myContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error:&authError)) {
myContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedRasonMessage) { success, error in
if (success) {
self.requestAuthenticationOutput = "Login successful"
}
else {
switch error.code {
case LAError.AuthenticationFailed.toRaw():
self.requestAuthenticationOutput = "Login failed"
case LAError.UserCancel.toRaw():
self.requestAuthenticationOutput = "User canceled"
case LAError.SystemCancel.toRaw():
self.requestAuthenticationOutput = "System canceled"
case LAError.UserFallback.toRaw():
self.requestAuthenticationOutput = "User pressed \"Enter Password\""
default:
self.requestAuthenticationOutput = "TouchID is not configured"
}
}
}
}
else {
switch authError!.code {
case LAError.TouchIDNotAvailable.toRaw():
self.requestAuthenticationOutput = "No Touch ID on device"
case LAError.TouchIDNotEnrolled.toRaw():
self.requestAuthenticationOutput = "No fingers enrolled"
case LAError.PasscodeNotSet.toRaw():
self.requestAuthenticationOutput = "No passcode set"
default:
self.requestAuthenticationOutput = "Something went wrong getting local auth"
}
}
self.statusLabel.text = self.requestAuthenticationOutput
}
在案例中,作为输出结果的一种方式,唯一能立即执行的是警报。
我不熟悉iOS编程,但我怀疑它与异步代码执行有关,但我还没有完全理解如何使用GCD/queues/等。如何让函数中的最后一行等待第一部分完成执行?任何想法都将不胜感激。(我使用的是swift,但测试ObjC也得到了同样的结果)任何时候你看到UI出现这样的问题时,你都应该考虑调用UI更改的线程 正在阅读有关评估政策的文档:。。。您将发现以下有用的注释: 该方法不会阻塞。相反,调用方必须提供一个应答块,以便在评估完成时异步调用。在未指定的线程上下文中,在框架内部的私有队列上执行该块。除此之外,不保证在哪个队列、线程或运行循环上执行块。
因为所有UI调用都必须在主线程上进行,我想如果您将UI调用分派到主线程(通过类似于
dispatch\u async()
)的方式),您将看到更好的结果。简单的回答是,您不能让代码等待指纹验证成功或失败(前提是设备能够)
获得所需效果的一种方法是在成功/错误块中获得结果后更新UI。由于此代码不在主(UI)线程上执行,因此需要使用GCD在主线程中执行此代码
下面列出了一个函数updateStatusLabel,它实现了这一点。即使在主线程中执行此操作——在API不可用的情况下,也将是完全安全的
func updateStatusLabel()
{
dispatch_async(dispatch_get_main_queue(),
{
self.statusLabel.text = self.requestAuthenticationOutput
})
}
var myContext:LAContext = LAContext()
var authError:NSError?
var myLocalizedRasonMessage = "Please authenticate using your fingerprint"
if (myContext.canEvaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, error:&authError)) {
myContext.evaluatePolicy(LAPolicy.DeviceOwnerAuthenticationWithBiometrics, localizedReason: myLocalizedRasonMessage) { success, error in
// ...Other code ommitted to set self.requestAuthenticationOutput
// Update UI
self.updateStatusLabel()
}
}
else {
switch authError!.code {
case LAError.TouchIDNotAvailable.toRaw():
self.requestAuthenticationOutput = "No Touch ID on device"
case LAError.TouchIDNotEnrolled.toRaw():
self.requestAuthenticationOutput = "No fingers enrolled"
case LAError.PasscodeNotSet.toRaw():
self.requestAuthenticationOutput = "No passcode set"
default:
self.requestAuthenticationOutput = "Something went wrong getting local auth"
}
}
self.updateStatusLabel()
}
非常感谢你!我已经尝试过使用dispatch_asyn,但是,我已经将所有内容都包装在其中,除了分配标签文本的行,结果证明我应该做完全相反的事情。