SwiftUI Data Flow Tidbits

Michael Chan
4 min readMar 25, 2020

--

You may have come across these @ signs if you’ve looked at some SwiftUI examples. These are actually Property Wrappers, which was introduced in Swift 5.1. In SwiftUI, there are a few which represents a style of data flow are within your application. This article takes a look at the most common ones used and the different scenarios in which you can use them.

This article assumes some knowledge on Property Wrappers from Swift 5.1 and a bit on SwiftUI.

@State

Summary for State in SwiftUI

A State is a property wrapped value that invalidates the view by “recomputing” the body. You should use the state as a source of truth for your view. A State should only been accessed within the view, so it is recommended to mark it as private. A State should be used when you want to use a value to represent the source of truth of the view that it is declared in. Use State when you want data flow within the view itself.

@Binding

Summary for Binding in SwiftUI

A Binding is a property wrapped value that provides a bi-directional connection between a view and it’s underlying model/source of truth. In the summary above, the summary uses the example of a Toggle view and a Boolean value of a State. The Toggle wants to have the ability to use a Boolean value to represent itself and make changes to the Boolean value when it is interacted in BUT it does not want to own it. The Binding property wrapper, in this case, is declared in the Toggle view. Use Binding when you want bi-directional data flow between yourself and the parent view, and don’t want ownership of the value.

ObservableObject, @Published

Summary for ObservableObject in SwiftUI

An ObservableObject is a protocol for classes that contains a objectWillChange publisher. An objectWillChange publisher lets any subscribers know that the object is going to change before making the updates. This is automatically synthesized for whomever conforms to the protocol. If the user of ObservableObject protocol wants to manually trigger the objectWillChange publisher, they can use the send() function on objectWillChange.

In the Summary, you can see the example of Contact class, it has 2 properties called name and age. They have the @Published keyword behind them.

Summary for Published in SwiftUI

Published is a property wrapped value that creates a Publisher for the value. In the summary for Published, you can see that the String, bar, is automatically created and is accessed via the $ sign.

What makes Published special in terms of ObservableObject is that, when you update the value of a @Published property, the objectWillChange publisher in an ObservableObject protocol will be automatically called for you.

The common use case for using ObservableObject is to update a view when the ObservableObject properties are updated. In order to use the ObservableObject in a view, it needs to use the @ObservedObject property wrapper.

@ObservedObject

Definition for ObservedObject in SwiftUI

From the declaration of ObservedObject, you can see that the generic type of it must conform to ObservableObject. You can also see from the description that ObservedObject subscribes to the ObservableObject ,aka objectWillChange publisher, and invalidate the view when there is a change. As you may realise, this is great for doing some sort of binding between an external model/object and a view.

@EnvironmentObject, @Environment

Summary for EnvironmentObject in SwiftUI

An EnvironmentObject property wrapper which is similar to what an ObservedObject does, where the generic type of the property wrapper needs to conform to ObservableObject but with 2 big differences. The first is it needs to be injected in the parent view by the environmentObject(_:) function an ancestor view. The second is that all children views of where the object got injected and the injected view, automatically has access to the object. So if you set the environmentObject from the SceneDelegate then every view will have access the ObservableObject. This makes it useful for tedious situations where you need to inject objects in various places of your view hierarchy.

So what is @Environment?

@Enviroment property wrapper is similar to @EnvironmentObject in the sense of access where all views are able to get these values. The difference being these are predetermined values injected for you.

Definition for Environment in SwiftUI

From the above, you can see that Environment actually has a predetermined set of values in the struct EnvironmentValues. If you take a look at the EnvironmentValues documentation/definition, there are lot of variables in there such as horizontalSizeClass, verticalSizeClass, locale, calendar, colorScheme etc.

--

--

No responses yet