SwiftUI - @Published

The @Published attribute is a property wrapper that allows access to a Publisher type using either the $ syntax or the projectedValue struct property.

@propertyWrapper public struct Published<Value> {
    /// Initialize the storage of the Published property as well as 
    /// the corresponding `Publisher`.
    public init(initialValue: Value)
    
    {…}
    
    /// The property that can be accessed with the `$` syntax and 
    /// allows access to the `Publisher`
    public var projectedValue: Published<Value>.Publisher { mutating  
    get }
}

A class using a @Published attribute must conform to the ObservableObject protocol — part of the Combine framework — which synthesizes an objectWillChange publisher that emits the changed value before any of its @Published properties changes .

Under the hood, the objectWillChange publisher will receive a new input whenever one of a @Published property is about to be mutated.

@Published works well with SwiftUI — coupled with a MVVM architecture — as one can make a view model conform the ObservableObject and mark its underlying properties as @Published so that views always reflect the latest model changes.

Creating a ViewModel class conforming to the ObservableObject enables us to work with a @Published property and process its underlying publisher.

class ViewModel: ObservableObject {
    @Published var keyword = ""
    func processKeyword() {
        self.$keyword // or self._keyword.projectedValue
            .debounce(for: 0.5, scheduler: DispatchQueue.main)
            .sink { self.sortArticles(byKeyword: $0) }
            .store(in: &cancellable)
    }
}

The sink method creates a subscriber and immediately receive values from the upstream publisher enabling us to sort the articles by keyword.

Notice how the $ syntax or projectedValue property from @Published is similar to the @State ones however both provide with different types — respectively a Publisher type and a Binding type — .

Because SwiftUI and Combine are tightly related, views observing these @Published properties will actually react to any new values emitted by their underlying publishers through the objectWillChange synthetizer.

— Conclusion

The @Published attribute is a great means of communication between the UI and its related data as one can observe a model object and reflect the UI with its latest changes.

It works well with the MVVM architecture as it enables us to observe the underlying stored properties through a publisher.

When conforming to the ObservableObject protocol, the system automatically synthesizes an objectWillChange publisher which will listen to the @Published properties mutations and send the information back to a view.