@StateObject & ObservableObject
@State is great for view-local values, but real apps share model objects across many views. That's the job of ObservableObject classes, @Published properties, and the ownership wrappers @StateObject and @ObservedObject — plus the modern @Observable macro.
Learn @StateObject & ObservableObject in our free Swift course — a beginner-friendly interactive lesson with worked examples, a practice exercise and a quick…
Part of the free Swift course at LearnCodingFast — hands-on lessons with examples you run in your browser, plus practice exercises and a quick quiz.
Building iOS Apps with SwiftUI • Intermediate
What You'll Learn in This Lesson
1️⃣ ObservableObject & @Published
A shared model is a class that conforms to ObservableObject . Mark each property that should trigger UI updates with @Published . It must be a class because observation needs reference semantics — one instance many views share.
2️⃣ @StateObject — Own the Model
Use @StateObject in the view that creates the model. SwiftUI keeps that single instance alive across refreshes, so its state never resets unexpectedly. Create it once, where it's born.
3️⃣ @ObservedObject — Observe a Passed-In Model
@ObservedObject does not own the object — it observes one handed in from a parent. Use it in child views. The pitfall: if you create a model with @ObservedObject , a refresh can recreate it and wipe its state. Own with @StateObject , observe with @ObservedObject .
4️⃣ The @Observable Macro (iOS 17+)
From iOS 17, the @Observable macro removes the boilerplate. You drop ObservableObject conformance and @Published ; tracked properties are observed automatically. In views you then own the model with plain @State .
Your turn. Fill in the blanks to make an observable model and own it in a view.
Build a GameModel: ObservableObject with a @Published var score = 0 and a scorePoint() method. Own it in a parent with @StateObject , and create a child ScoreBadge that takes the model via @ObservedObject and shows the live score. Then rewrite it using the iOS 17 @Observable macro.
Practice quiz
What is ObservableObject?
- A SwiftUI view
- A protocol for reference-type model classes that publish changes
- A property wrapper
- A struct modifier
Answer: A protocol for reference-type model classes that publish changes. ObservableObject is a protocol adopted by a class so SwiftUI can observe its published changes.
Why must an ObservableObject be a class, not a struct?
- Structs cannot have functions
- It needs reference semantics so views share one instance
- Classes are faster
- The protocol forbids structs
Answer: It needs reference semantics so views share one instance. Shared, observable model state needs reference semantics — a single instance many views reference.
What does the @Published property wrapper do?
- Stores data on disk
- Announces changes so observing views refresh
- Makes a property private
- Marks a constant
Answer: Announces changes so observing views refresh. @Published emits a change notification whenever the property's value changes, refreshing observers.
Which wrapper CREATES and OWNS an observable object?
- @ObservedObject
- @Binding
- @State
- @StateObject
Answer: @StateObject. @StateObject creates and owns the object, keeping it alive across view re-creations.
Which wrapper observes an object passed in from elsewhere?
- @StateObject
- @ObservedObject
- @State
- @Published
Answer: @ObservedObject. @ObservedObject does NOT own the object; it observes an instance handed to it.
What is the danger of using @ObservedObject to create an object inline?
- It is illegal Swift
- The object may be recreated and lose its state on a refresh
- It runs too slowly
- It cannot publish changes
Answer: The object may be recreated and lose its state on a refresh. @ObservedObject doesn't own the object, so a view refresh can recreate it and discard its state; use @StateObject to own it.
Where should you create a view model with @StateObject?
- In the view that owns it, once
- In every child view
- In the App delegate only
- Never create it
Answer: In the view that owns it, once. Create it with @StateObject in the owning view so SwiftUI keeps the single instance alive.
What does the @Observable macro (iOS 17+) replace?
- The View protocol
- Manually conforming to ObservableObject and marking @Published
- The @State wrapper
- NavigationStack
Answer: Manually conforming to ObservableObject and marking @Published. @Observable lets you drop ObservableObject conformance and @Published; tracked properties are observed automatically.
With the @Observable macro, how do you own a model in a view?
- @StateObject
- @State
- @Published
- @Binding
Answer: @State. With @Observable, you use plain @State to own the model instance in the view.
When several views need the same shared model, you should...
- Copy it into each view
- Use @State in each
- Reference one instance via @StateObject/@ObservedObject
- Avoid sharing entirely
Answer: Reference one instance via @StateObject/@ObservedObject. Share a single reference-type instance so all views see and react to the same data.