Chapters

Hide chapters

SwiftUI Cookbook

Live Edition · iOS 16.4 · Swift 5.8.1 · Xcode 14.3.1

Sharing State Across Views With Environment Objects
Written by Team Kodeco

While ObservableObject and ObservedObject are great for sharing state between views, they require you to pass the state manually from parent to child. But what if you want to share data across multiple views in your app without explicitly passing it around? That’s where environment objects come in.

SwiftUI’s EnvironmentObject property wrapper provide a way to share data across your entire app. You can think of them as a global store for your data that any view can access. This is particularly useful when you have deeply nested views and don’t want to pass data through multiple layers.

To use an environment object, you first need to define your data model as an ObservableObject. For example, let’s create a GameSettings object that holds the score of a game.

class GameSettings: ObservableObject {
  @Published var score = 0
}

Then, in the root of your app, you provide this object to your view hierarchy using the environmentObject modifier.

struct ContentView: View {
  var body: some View {
    GameView()
      .environmentObject(GameSettings())
  }
}

Now, any view in the hierarchy can access GameSettings using the EnvironmentObject property wrapper.

struct GameView: View {
  @EnvironmentObject var settings: GameSettings

  var body: some View {
    VStack {
      Text("Score: \(settings.score)")
      Button("Increment Score") {
        settings.score += 1
      }
    }
  }
}

Here’s what the preview looks like:

Use EnvironmentObject to make data available throughout your app.
Use EnvironmentObject to make data available throughout your app.

In this example, GameView has access to the GameSettings object and can update the score. When the button is pressed, the score is incremented, and the Text view is automatically updated because it observes the GameSettings object.

Note: The EnvironmentObject property wrapper doesn’t provide a default value. The object must be provided somewhere in the ancestor views using .environmentObject(_:) or your app will crash.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2024 Kodeco Inc.