我正在努力解决以下问题:
在async函数中启动一些网络处理:
func upload(
object: object,
context: NSManagedObjectContext
) async -> Dictionary<String,String> {
}
因此,为了通知用户一个耗时的进程刚刚启动,我显示了一个警报控制器:
let alert = UIAlertController(
title: "Loading",
message: "Please wait...",
preferredStyle: .alert
)
self.present(alert, animated: true, completion: nil)
在函数的最后如果一切都按计划进行我就会成功地解散那个警报控制器,并显示另一个警报:
alert.dismiss(
animated: true,
completion: {
let messageAlert = UIAlertController(
title: "Success",
message: "Upload complete",
preferredStyle: .alert
)
messageAlert.addAction(
UIAlertAction(
title: "OK",
style: .default,
handler: { (action: UIAlertAction) in
//
}
)
)
self.present(
messageAlert, animated: true, completion: nil
)
}
)
但是我还想在发生错误时解散那个警报并显示一个新的警报,但是第一个警报控制器永远不会被解散
guard dataString.replacingOccurrences(
of: "n",
with: ""
) != "no valid userID" else {
error = true
alert.dismiss(
animated: true,
completion: {
let messageAlert = UIAlertController(
title: "Warning",
message: "no valid userID received",
preferredStyle: .alert
)
messageAlert.addAction(
UIAlertAction(
title: "OK",
style: .default,
handler: { (action: UIAlertAction) in
//
}
)
)
self.present(
messageAlert,
animated: true,
completion: nil
)
}
)
returnDic = [
"result": "error",
"info": "no valid userID received"
]
return returnDic
}
我就是不明白为什么我能在函数结束时关闭它,而不是在路上的某个地方…Xcode还抱怨说,如果现在正在显示一个新的警报,则无法呈现一个新的警报。
[Presentation] Attempt to present <UIAlertController: 0x15880a200> on
<Project.ContainerViewController: 0x153708290> (
from <Project.LockerViewController: 0x155018200>)
while a presentation is in progress.
我已经尝试过使用观察者:
var error = Bool() {
didSet {
alert.dismiss(animated: true)
}
}
它被调用,但视图不会再次被解散:/
任何想法?
您还可以使用延续来等待警报的表示和解除。
更多细节在这里
extension UIViewController {
@MainActor
public func present(_ alert: UIViewController, animated: Bool) async {
await withCheckedContinuation { continuation in
present(alert, animated: animated) {
continuation.resume()
}
}
}
@MainActor
public func dismiss(animated: Bool) async {
await withCheckedContinuation { continuation in
dismiss(animated: animated) {
continuation.resume()
}
}
}
}
然后调用
await self.present(alert, animated: true)
await alert.dismiss(animated: true)
我找到了一个解决方案:问题是警报控制器的呈现还没有完成,所以当时它还不能被解除。
解决这个问题的方法是:
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
alert.dismiss(animated: true)
}
我已经意识到这与附加一个闭包块
self.present(alert,animated: true) { print("alert controller is visible") }
并且在解雇时该文本尚未打印出来;)
我希望这对其他人也有用;)