未显示警报,因为“不允许从视图更新中发布更改”

问题描述 投票:0回答:1

我实现了 async/await 和 Result。我的数据适配器 (DA) 中抛出的错误被正确路由到我的域存储 (DoS) 中,并在结果 .failure 情况下进行处理,如下所示。

但我很难将错误显示为警报。收到以下消息。

Publishing changes from within view updates is not allowed, this will cause undefined behavior.

我的域名商店如下所示:

@MainActor
class TaskDoS: ObservableObject{
    @Published var tasks: [TaskModel] = []
    @Published var errorMessage: String = ""
    @Published var showingError = false
    
    var dataDS: TaskDS
    
    init(dataDS: ITaskDataService) {
        self.dataDS = TaskDS(dataDA: dataDS)
    }
    
    //loader for tasks.
    func loadTasks() async {
        let result = await dataDS.readTasks()
        
        switch result {
        case .success(let tasks):
            self.tasks = tasks
        case .failure(let error):
            
            //I tried to run this code inside a DispatchQueue.main.async closure but without effects.
            self.errorMessage = error.guidance
            self.showingError.toggle()
            
            DebugPrint.value(error, prompt: "TaskDoS:loadTask:")
        }
    }
}

相应的屏幕如下所示:

struct TaskListScreen: View {
    @EnvironmentObject private var taskDoS: TaskDoS
    @State private var editTask: String = "" //mock type.
    
    var selectedCatalogue: String = "mockTaskCopy" //mockTaskPaste.
    
    var body: some View {
        NavigationStack {
            List {
                ForEach(taskDoS.tasks) { task in
                    Text(selectedCatalogue == "mockTaskCopy" ? "copy task\(task)" : "paste task\(task)")
                }
            }
            .task {
                await taskDoS.loadTasks()
            }
            //this alert can't be shown.
            .alert("Error", isPresented: $taskDoS.showingError) {
            } message: {
                Text(taskDoS.errorMessage)
            }
        }
    }
}
swiftui
1个回答
0
投票

通常,异步函数不会在对象内部声明,因为它会尝试使用

self
,这可能会导致问题。即把它放在其他地方并让它返回结果,例如

func loadItems() async throws -> [Item] {

然后你可以这样做:

.task {
    do {
        let items = await loadItems()
        self.result = .success(items)
    }
    catch {
        self.result = .failed(error)
    }
}

注意,我将您的

Task
重命名为
Item
,因为这会与异步
Task
发生冲突。

© www.soinside.com 2019 - 2024. All rights reserved.