Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to publish change from async function

I have class conforms to ObservableObject with

@Published var fileContent = ""

defined. Further I have getFileContent() async function returning String. If I call function like this

Task {
    fileContent = await getFileContent(forMeasurementID: id, inContext: context)
}

code is compiled and app works fine but XCode is complaining "purple" error "Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.". I've tried to elaborate with receive(on:) but no succeess so far. I will appreciate any hint. Thanks.

like image 622
Dawy Avatar asked Oct 13 '25 03:10

Dawy


2 Answers

Well, in async/await world it is better to use MainActor, e.g.

Task {
    let content = await getFileContent(forMeasurementID: id, inContext: context)
    await MainActor.run {
        // fileContent will be updated on the Main Thread
        fileContent = content
    }
}
like image 173
Marius Kažemėkaitis Avatar answered Oct 14 '25 17:10

Marius Kažemėkaitis


You cannot change the state of your app (change a @Published var) unless you are in the main thread.

Here is how your code works:

Task {
    let content = await getFileContent(forMeasurementID: id, inContext: context)
    DispatchQueue.main.async {
        fileContent = content
    }
}
like image 32
HunterLion Avatar answered Oct 14 '25 18:10

HunterLion