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

How to Use @EnvironmentObject in SwiftUI for Shared Data

Use @EnvironmentObject in SwiftUI to share a data model across multiple views without passing it explicitly. Declare a shared observable object with ObservableObject, inject it with .environmentObject() on a parent view, and access it in child views using @EnvironmentObject property wrapper.
๐Ÿ“

Syntax

The @EnvironmentObject property wrapper lets a SwiftUI view access an observable object shared in the environment. You declare a class conforming to ObservableObject to hold your data. Then you inject it into the view hierarchy using .environmentObject(). Child views read it with @EnvironmentObject without needing to pass it manually.

  • ObservableObject: A class that holds data and notifies views when data changes.
  • @EnvironmentObject: Property wrapper to access shared data from environment.
  • .environmentObject(): Modifier to inject the shared object into the view hierarchy.
swift
class UserSettings: ObservableObject {
  @Published var username: String = "Guest"
}

struct ContentView: View {
  @EnvironmentObject var settings: UserSettings

  var body: some View {
    Text("Hello, \(settings.username)!")
  }
}

// Inject in parent view
ContentView().environmentObject(UserSettings())
Output
Hello, Guest!
๐Ÿ’ป

Example

This example shows a shared UserSettings object injected at the root. The ContentView and its child ProfileView both access and update the username via @EnvironmentObject. Changes in one view reflect automatically in the other.

swift
import SwiftUI

class UserSettings: ObservableObject {
  @Published var username: String = "Guest"
}

struct ContentView: View {
  @EnvironmentObject var settings: UserSettings

  var body: some View {
    VStack {
      Text("Hello, \(settings.username)!")
      ProfileView()
    }
  }
}

struct ProfileView: View {
  @EnvironmentObject var settings: UserSettings

  var body: some View {
    TextField("Username", text: $settings.username)
      .textFieldStyle(RoundedBorderTextFieldStyle())
      .padding()
  }
}

@main
struct MyApp: App {
  var settings = UserSettings()

  var body: some Scene {
    WindowGroup {
      ContentView().environmentObject(settings)
    }
  }
}
Output
UI with a greeting text "Hello, Guest!" and a text field below it to edit the username. Typing in the text field updates the greeting in real time.
โš ๏ธ

Common Pitfalls

  • Not injecting the ObservableObject with .environmentObject() causes runtime crashes because the environment object is missing.
  • Declaring @EnvironmentObject in a view without the matching object in the environment leads to a crash.
  • Using @ObservedObject or @StateObject instead of @EnvironmentObject when you want shared data across many views.
swift
struct ChildView: View {
  @EnvironmentObject var settings: UserSettings

  var body: some View {
    Text("Username: \(settings.username)")
  }
}

// Wrong: Forgetting to inject environment object
// This will crash at runtime
// ChildView()

// Right: Inject environment object in parent
ChildView().environmentObject(UserSettings())
Output
Crash if environment object missing; shows username text if injected properly.
๐Ÿ“Š

Quick Reference

ConceptDescriptionUsage
ObservableObjectClass that holds shared data and notifies viewsclass MyData: ObservableObject { @Published var value = 0 }
@EnvironmentObjectProperty wrapper to access shared data in views@EnvironmentObject var data: MyData
.environmentObject()Modifier to inject shared object into view hierarchyContentView().environmentObject(MyData())
Common ErrorMissing injection causes crashAlways inject with .environmentObject()
โœ…

Key Takeaways

Use @EnvironmentObject to share observable data across many SwiftUI views without manual passing.
Inject your ObservableObject into the view hierarchy with .environmentObject() on a parent view.
Access the shared data in child views using @EnvironmentObject property wrapper.
Always ensure the environment object is injected to avoid runtime crashes.
Use @EnvironmentObject for global or widely shared data, not for local state.