0
0
Ios-swiftHow-ToBeginner ยท 3 min read

How to Use @ObservedObject in SwiftUI for Data Binding

Use @ObservedObject in SwiftUI to connect a view to an external data model that conforms to ObservableObject. This lets the view automatically update when the model changes by observing its @Published properties.
๐Ÿ“

Syntax

The @ObservedObject property wrapper is used inside a SwiftUI view to observe an external data model that conforms to ObservableObject. The model must have properties marked with @Published to notify changes.

  • @ObservedObject var model: ModelClass declares the observed object.
  • class ModelClass: ObservableObject defines the model.
  • @Published var property marks properties that trigger UI updates.
swift
class Counter: ObservableObject {
  @Published var count = 0
}

struct ContentView: View {
  @ObservedObject var counter: Counter

  var body: some View {
    Text("Count: \(counter.count)")
  }
}
๐Ÿ’ป

Example

This example shows a simple counter app where the view updates automatically when the count changes in the observed object.

swift
import SwiftUI

class Counter: ObservableObject {
  @Published var count = 0

  func increment() {
    count += 1
  }
}

struct ContentView: View {
  @ObservedObject var counter = Counter()

  var body: some View {
    VStack(spacing: 20) {
      Text("Count: \(counter.count)")
        .font(.largeTitle)
      Button("Increment") {
        counter.increment()
      }
    }
    .padding()
  }
}

@main
struct MyApp: App {
  var body: some Scene {
    WindowGroup {
      ContentView()
    }
  }
}
Output
A screen showing "Count: 0" and a button labeled "Increment". Each tap on the button increases the count number displayed.
โš ๏ธ

Common Pitfalls

  • Not marking the model class with ObservableObject prevents updates.
  • Forgetting @Published on properties means changes won't notify the view.
  • Using @ObservedObject for a model created inside the view can cause unexpected behavior; prefer passing the model from a parent view.
  • Confusing @ObservedObject with @StateObject: use @StateObject when the view owns the model instance.
swift
class Model: ObservableObject {
  @Published var value = 0 // Fixed missing @Published
}

struct View: View {
  @ObservedObject var model = Model() // Model created here

  var body: some View {
    Text("Value: \(model.value)")
  }
}

// Correct way:
class ModelCorrect: ObservableObject {
  @Published var value = 0
}

struct ParentView: View {
  @StateObject var model = ModelCorrect()

  var body: some View {
    ChildView(model: model)
  }
}

struct ChildView: View {
  @ObservedObject var model: ModelCorrect

  var body: some View {
    Text("Value: \(model.value)")
  }
}
๐Ÿ“Š

Quick Reference

  • @ObservedObject: Use in views to observe external ObservableObject models.
  • ObservableObject: Protocol for data models that can be observed.
  • @Published: Marks properties that trigger view updates.
  • @StateObject: Use when the view owns the model instance.
โœ…

Key Takeaways

Use @ObservedObject to connect a SwiftUI view to an external ObservableObject model.
Mark model properties with @Published to trigger UI updates when they change.
Use @StateObject when the view creates and owns the model instance, not @ObservedObject.
Passing the model from a parent view to child views with @ObservedObject keeps data in sync.
Forgetting ObservableObject or @Published prevents the view from updating automatically.