我试图在 asnyc 抛出函数错误时弹出警报,但它似乎不起作用。 以下是视图中元素的简化版本: 我在视图顶部声明:
@State private var onError: Bool = false
然后按钮调用异步函数:
Button {
Task {
await wait()
}
} label: {
Text("Button")
}
.alert(isPresented: $onError) {
Alert(title: Text("An Error has occured!"), dismissButton: .cancel())
}
它本身调用异步抛出函数:
private func wait() async {
do {
try await someAsyncThrowingFunc()
} catch {
print(error)
// onError = true
DispatchQueue.main.async{
onError = true
}
}
}
出现错误时,会打印错误消息,但不会弹出警报。
我也尝试过直接向按钮抛出错误
private func wait() async throws {
do {
try await someAsyncThrowingFunc()
} catch {
print(error)
throw error
}
}
或者甚至将 Bool 返回给按钮
private func wait() async -> Bool {
do {
try await someAsyncThrowingFunc()
} catch {
print(error)
return true
}
return false
}
但是没关系,弹出窗口永远不会显示。
我真的不知道还能做什么才能让它发挥作用;所以提前感谢您的帮助。
它是
.task
不是 Task
并且您不能使用 DispatchQueue
,因为 View
是结构值类型而不是类引用类型,请尝试一下:
Button {
running.toggle()
} label: {
Text(running ? "Stop" : "Start")
}
.task(id: running) {
if !running {
return
}
await wait()
running = false
}
.alert(isPresented: $onError) { [onError] in
Alert(title: Text("An Error has occured!"), dismissButton: .cancel())
}
...
private func wait() async {
do {
results = try await someAsyncThrowingFunc()
} catch {
print(error) // cancel error if Button is toggled while running
onError = true
}
}
好吧,我的错,我想问题实际上来自于这个视图嵌入到另一个视图中这一事实。正如另一个(thread)中提到的,一个简单的修复是:
public struct EmbededView: View {
@Binding var showAlert: Bool
@Binding var alert: Alert?
public init(showAlert: Binding<Bool>, alert: Binding<Alert?>) {
self._showAlert = showAlert
self._alert = alert
}
public var body: some View {
...
Button {
Task {
await wait()
}
} label: {
Text("Try")
}
...
}
private func wait() async {
do {
try await someAsyncThrowingFunc()
} catch {
print(error)
alert = Alert(title: Text("An Error has occured!"), dismissButton: .cancel())
self.showAlert.toggle()
}
}
}
public struct TopLevelView: View {
@State private var showAlert = false
@State private var alert: Alert? = nil
public var body: some View {
ScrollView {
...
EmbededView(howAlert: $showAlert, alert: $alert)
...
}
.alert(isPresented: $showAlert) {
alert!
}
}
}
感谢您的帮助,如果有人遇到同样的问题,希望此解决方案可以有所帮助。