Hey, hi, hello! Today we're diving deep into the observer design pattern and how Swift and SwiftUI have brought a fresh take to this classic concept with Observables.
Observables are a new way to manage and respond to data changes in your app, providing more flexibility and type safety than ever before. Say goodbye to
@ObservableObject and let's embrace Observables.
Observation supports subclassing of observable types. If you have an observable class that supports subclassing, don’t include the
finalkeyword in the class declaration. Including
finalprevents subclassing of the type.
Note, you need to
import Observationto use this functionality.
Creating an Observable Object
Creating an observable type is incredibly simple in Swift. All it requires is attaching the
@Observable macro to the type declaration. This macro takes care of everything needed to make the type observable, from declaring to implementing the Observable protocol. It does all of this during compile time, ensuring your runtime performance isn't impacted.
In our workout example, let's consider the
In this example, our
Workout class is now observable, meaning any changes in its properties, such as
intensity, can be tracked and acted upon.
With our observable
Workout class in place, the Observation framework allows us to:
- Identify the
Workoutclass as an observable type.
- Keep an eye on alterations within any
- Use these changes to trigger actions elsewhere, such as updating an app’s user interface.
The Observation framework handles the hard work of managing observers and notifications, allowing us to focus on reacting to the changes that matter in our application.
Bringing Observables into SwiftUI
SwiftUI's reactive nature works harmoniously with Swift's Observation framework. This potent combination allows for seamless tracking and reaction to changes in our app's state, directly influencing the UI. Let's see how this works in our workout scenario.
Consider we have a SwiftUI
View that displays our workout details. We can make this
View reactive to changes in an
WorkoutView establishes a dependency on the
workout instance of our
Workout class. Whenever the
workout instance undergoes a change in its properties (
WorkoutView automatically reflects these changes in the UI.
Note that here we have nothing in the view that observed the
intensityproperty, so if any changes occur to the workout’s intensity, the view will not update.
In order to make changes to the view, we’ll add a
Button that toggles the workout state to “in progress”.
Now that we’ve added a way to change the state of a property in out
Observable object, out view knows to track changes to this property and update the view accordingly, without needing to add the
@Published property wrapper.
With the power of Observation, we can track changes in computed properties that use another property in the class. Let's demonstrate this by adding a computed property
status to the
Workout class. The
status will be a string that tells us whether the workout is in progress or not and how long the workout will last.
Here's how we can update our
status property is computed based on the
inProgress property and also incorporates the
duration property. When
true, it returns a string indicating the workout is in progress and shows the duration of the workout. If
false, it simply states that the workout has not started.
Now, let's incorporate this into our
Text(workout.status) to display the status of the workout. Also, in the button action, we've added an operation to increase the duration of the workout by 10 minutes each time the workout starts.
Now, when you toggle the workout's
inProgress state, SwiftUI will not only update the button label, but also the
status text. This is because the
status computed property depends on
duration, both of which SwiftUI is observing for changes.
Mastering Swift's Observable objects is crucial for SwiftUI development. They provide a powerful and flexible way to track state changes in your app and to keep your UI up-to-date with your data.
In this post, we've delved into creating an Observable object and using it within SwiftUI views. We've seen how changes to the Observable object's properties can be tracked and reflected in the UI. We've also explored how computed properties can be observed and how these changes affect our SwiftUI views.
The ability to correctly use and manage Observable objects in SwiftUI is an essential skill for any Swift developer. Keep experimenting and keep learning - I’d love to know how you use Observables in your projects.