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      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.