SwiftUI: Exploring ObservableObject, ObservedObject, StateObject, and EnvironmentObject

Chaitali Lad
4 min readAug 1, 2023

--

With SwiftUI’s advanced tools, you can create dynamic user interfaces and share data across views easily. Discover ObservableObject, ObservedObject, StateObject, and EnvironmentObject, and learn how to leverage them effectively in your SwiftUI projects.

State Management in SwiftUI:

In SwiftUI, state management is vital for maintaining up-to-date data in your app’s user interface. It ensures smooth user experiences by efficiently updating views as the data changes. SwiftUI offers elegant mechanisms to handle the state effectively.

ObservableObject:
The ObservableObject protocol enables the creation of objects that automatically notify their subscribers about any changes. By adopting this protocol and using the @Published property wrapper, you can effortlessly make certain properties of an object observable.

@Published : It is a property wrapper in Swift that automatically broadcasts any changes made to a property to its subscribers. It is commonly used with the ObservableObject protocol to create reactive and observable objects. When the value of a property marked with @Published changes, the object notifies its subscribers, enabling them to react to the updates.

Let’s check out an example:

ProfileData class conforms to the ObservableObject protocol which means it will be able to propagate changes to its subscribers. Inside ProfileData, we have a property named username that is marked with the @Published property wrapper which allows automatic broadcasting of any changes to this property.

Use of ObservableObject

We have created a SwiftUI view called ProfileView. Inside this view, we created an instance of ProfileData using the @ObservedObject property wrapper. This enables the view to observe changes in the ProfileData object. The ProfileView displays the initial value of username, which is "Claire Mcphee." If the user changes the text in the TextField, the @Published property wrapper automatically triggers an update to the username property. This change is then propagated to any subscribers observing profileData, causing the Text component to update and display the new username.

ObservedObject:
ObservedObject is a property wrapper that is used within SwiftUI views to observe changes to an ObservableObject. When a property of a view is marked with @ObservedObject, SwiftUI automatically subscribes to changes in the object and the view is updated whenever the object's @Published properties change.

Let’s take another example: ProfileData acts as an ObservableObject with two properties: username and age. The @Published property wrapper is applied to both properties to make them observable. The ProfileView is a SwiftUI view that utilizes the @ObservedObject property wrapper to automatically observe changes to the ProfileData object. It displays the username, age, and an "Increment Age" button.

Example of ObservedObject

When the button is pressed, the incrementAge() method is called, increasing the age property. SwiftUI automatically detects the change through @Published, updates the view, and reflects the updated age value on the screen without requiring manual property observation or binding.

StateObject:
The StateObject property wrapper manages the lifecycle of reference-type objects within a SwiftUI view. It automatically creates and preserves the object across view updates, ensuring its state persists consistently.

The above example remains the same, but instead of using @ObservedObject, we use @StateObject .The ProfileView now uses the @StateObject property wrapper to create and manage the ProfileData object. The usage is similar to @ObservedObject, but with @StateObject, SwiftUI takes care of creating the ProfileData object and preserving it across view updates. Any changes made to the age property in the ProfileData class will automatically trigger updates to the ProfileView, just as before.

The key difference between @StateObject and @ObservedObject is that @StateObject is designed to be used within a single view, while @ObservedObject is meant to share the same object instance across multiple views. This means that SwiftUI will automatically handle the lifecycle of the @StateObject, creating it when needed and destroying it when the view is no longer in use.

EnvironmentObject:
The @EnvironmentObject property wrapper allows you to share data across multiple views in a SwiftUI hierarchy. It eliminates the need for manual passing of data through view hierarchies and provides a global approach to data sharing. It allows you to inject an object at the top level of the view hierarchy and access it from any view below that level.

Here’s an example: The ProfileData class is defined with properties for username and age, both marked with @Published for automatic updates. The MyApp structure sets ProfileData as an environment object in its WindowGroup, allowing it to be accessible to all child views.

Example of EnvironmentObject

ParentView and ProfileView access the shared profileData object using @EnvironmentObject, displaying and incrementing the age. Any changes made to profileData are automatically reflected in both views, demonstrating the global approach to data sharing that @EnvironmentObject provides in SwiftUI.

Note: To use @EnvironmentObject, you need to ensure that the view hierarchy has access to the environment object. In this example, we set it in the MyApp's WindowGroup. Additionally, the @EnvironmentObject property wrapper requires that the object is available in the environment, so don't forget to set it using .environmentObject() wherever necessary in the view hierarchy.

Choosing the Right Approach:
When selecting the appropriate state management technique in SwiftUI, consider the context and requirements of your app. ObservedObject is suitable for managing external objects, EnvironmentObject excels at sharing data across views, StateObject preserves object lifecycles, and ObservableObject facilitates granular observation of specific properties.

Conclusion:
We explored the core concepts of state management in SwiftUI. By leveraging ObservableObject, ObservedObject, StateObject, and EnvironmentObject, you can effectively manage state, share data, and build robust, reactive user interfaces. Experiment with these powerful tools and incorporate them into your SwiftUI projects for a seamless and delightful user experience.

Thank you for reading this blog post! If you found it helpful and informative, please consider giving it a like and sharing it with others who might benefit from it. Your support motivates me to continue creating content like this. Stay tuned for more upcoming blogs related to SwiftUI. Remember to follow me to stay updated on the latest SwiftUI content and be notified when new blog posts are published.
Happy coding! 👩🏻‍💻

--

--