@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.