UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: Message Publishing changes from background threads is not allowed

Forums > SwiftUI

In my project I load JSON data from a server and display it in a list. I have a class NetworkManager which handles the POST, GET and DELETE tasks. Inside .onAppear() of the MeterView Struct I load the data from the server.

.onAppear() {
                networkManager.getMeterReadingItems { items in
                    readings.items = items
                }
            }

When I start the app it works at first with no apparent problems, however I see the following error message in the console (Xcode) which refers to the "networkManager..." line:

[SwiftUI] 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 found the following article by Paul on Hacking with Swift: How to use @MainActor to run code on the main queue and tried various things, but unfortunately without success. I must confess I don't know how to prevent the message.

I have tried using a Task in .onAppear - no success:

            .onAppear() {
                Task {
                    await MainActor.run {
                        networkManager.getMeterReadingItems { items in
                            readings.items = items
                        }
                    }
                }
            }

Can anyone give me a tip on how to prevent the message and thus improve the code?

2      

Try this:

.onAppear {
    networkManager.getMeterReadingItems { items in
        DispatchQueue.main.async {
            readings.items = items
        }
    }
}

Or switch to using async/await instead of callback-based methods.

3      

Hi roosterboy, Thanks a lot - that fixed it :-)

2      

It would be nicer to figure out how to do it with async/await instead of GCD.

Try marking your NetworkManager class @MainActor.

2      

Hi @bobstern, after reading Paul's post about @MainActor my first attempt was to mark the NetworkManager class as @MainActor. Unfortunately after that the message in Xcode about the above mentioned line was still displayed .... ??!!

After that I wrote the article here in the forum and after roosterboy's change Xcode didn't give a warning anymore. I do not know what I did wrong regarding @MainActor or maybe that alone was not enough.

2      

Hacking with Swift is sponsored by Essential Developer

SPONSORED Join a FREE crash course for mid/senior iOS devs who want to achieve an expert level of technical and practical skills – it’s the fast track to being a complete senior developer! Hurry up because it'll be available only until April 28th.

Click to save your free spot now

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.