BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

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      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

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.