@Published properties and the main thread

I am working on a library, a Swift package. We have quite a few properties on various classes that can change and we think the @Published property wrapper is a good way to annotate these properties as it offers a built-in way to work with SwiftUI and also Combine.

Many of our properties can change on background threads and we've noticed that we get a purple runtime issue when setting the value from a background thread. This is a bit problematic for us because the state did change on a background thread and we need to update it at that time. If we dispatch it to the main queue and update it on the next iteration, then our property state doesn't match what the user expects. Say they "load" or "start" something asynchronously, and that finishes, the status should report "loaded" or "started", but that's not the case if we dispatch it to the main queue because that property doesn't update until the next iteration of the run loop.

There also isn't any information in the documentation for @Published that suggests that you must update it on the main thread. I understand why SwiftUI wants it on the main thread, but this property wrapper is in the Combine framework. Also it seems like SwiftUI internally could ask to receive the published updates on the main queue and @Published shouldn't enforce a specific thread.

One thing we are thinking about doing is writing our own property wrapper, but that doesn't seem to be ideal for SwiftUI integration and it's one more property wrapper that users of our package would need to be educated about.

Any thoughts on direction? Is there anyway to break @Published from the main thread?

Ultimately, all UI updates must occur on the main thread. What you seem to be asking here is for SwiftUI to internally switch to the main thread if a Published property is updated on a different thread. What difference would that make?

No, I was asking if SwiftUI internally asked for the updates on the main thread, ie using something like receive(on:) The publisher wouldn't change. I realize it's probably too late for anything like that. But looking for clarification and direction.

1 Like

Did you ever discover the answer to this question?

Unfortunately we had to resort to implementing our own property wrapper. This was before the Observable stuff that is out now. We could never find a way to make @Published work the way we needed it to WRT the main thread.

1 Like

Ah I see. Thank you for sharing!

I assume you’re referring to the newer Observation Framework.