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

SOLVED: Error: Publishing changes from background threads is not allowed

Forums > SwiftUI

I receive this 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.

When I have my code as such:

@StateObject var lokSettings: LOKSettings         = LOKSettings()

var body: some Scene {

    ContentView()
        .task {
            await startUp()
        }
}

func startUp() async {

    // --- other startup code here ---

    do {
        lokSettings.settings = try await Settings.getLatest() // error here.
    } catch {
        print(error.localizedDescription)
    }
}

but the error does not show up when it's out of startUp() and inside the .task { } like so:

ContentView()
    .task {
        await startUp()
        do {
            lokSettings.settings = try await Settings.getLatest() // NO error here.
        } catch {
            print(error.localizedDescription)
        }
    }

lokSettings.settings is a @Published property inside lokSettings.

Can someone explain to me what the difference is? Aren't I just moving the block of code from one async func to another ?

thanks,

2      

There is a difference between main thread and main queue. UI udpates have to be done on the main thread. The function in the first example is on a different queue that could be on the main thread, but it is not guaranteed so you need to take appropriate action such as suggested or use @MainActor.

Main thread vs main queue

MainActor

5      

Perfect.

From the links above about the @MainActor

@MainActor is a global actor that uses the main queue for executing its work. In practice, this means methods or types marked with @MainActor can (for the most part) safely modify the UI because it will always be running on the main queue,

and

it’s a good idea to add the @MainActor attribute to all your observable object classes to be absolutely sure all UI updates happen on the main actor. If you need certain methods or computed properties to opt out of running on the main actor, use nonisolated as you would do with a regular actor.

thanks @greenamberred. :)

3      

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!

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.