Integrate Combine Into an App

Aug 5 2021 · Swift 5.4, macOS 11.3, Xcode 12.5

Part 1: Define a View Model

02. Use @Published to Publish State

Episode complete

Play next episode

Next
About this episode
Leave a rating/review
See forum comments
Cinema mode Mark complete Download course materials
Previous episode: 01. Identify Where to Use Combine Next episode: 03. Create Data Publishers

Get immediate access to this and 4,000+ other videos and books.

Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and 4,000+ professional videos in a single subscription, it's simply the best investment you can make in your development career.

Learn more Already a subscriber? Sign in.

Transcript: 02. Use @Published to Publish State

SwiftUI’s tight integration with Combine means that the publisher-subscriber paradigm is presented in a different way from what you’re used to from previous examples. In fact, the paradigm is almost entirely hidden from you, only exposing some hooks via property wrappers and interfaces.

Decorating a property of a SwiftUI view with the @State property wrapper sets up a Combine-based connection behind the scenes between the view and that property. When that property changes, the new value is published, and the View - acting as the subscriber in this case - is asked by the rendering system to redraw itself. Bindings are passed into SwiftUI views to allow the view to change the property’s value.

But what if you have an object that is outside a SwiftUI view? @State and Binding won’t work here - they deal with properties within a SwiftUI view.

Luckily, the @Published property wrapper exits for just such a case. @Published properties get publishers synthesized for them behind the scenes, which you can access via the $ prefix — e.g., $fetching, just like with a Binding. Let’s go over to the code and add the property wrappers.

To enable published values in our model, go to the ChuckNorrisJokesModel target, and open the View Model folder and select the JokesViewModel.swift file. Below the line that creates the decoder, define the following state properties, decorating them with an @Published property wrapper:

@Published public var fetching: Bool = false
@Published public var joke: Joke = Joke.starter
@Published public var backgroundColor = Color("Gray")
@Published public var decisionState: DecisionState = .undecided
@Published public var showTranslation = false

If you were to run the app now, you wouldn’t see the app respond to any changes to these properties, since nothing subscribes to these publishers yet; we’ll revisit this later when we hook up the view to the view model.