You may think of @EnvironmentObject
as a shared data a that multiple views could use to get the data. This should be used if your data will be shared across many parts of the app.
A property wrapper type for an observable object supplied by a parent or ancestor view.
Apple Documentation
In this tutorial, you’ll learn what is @EnvironmentObject
in SwiftUI. You’ll learn:
- How to use
@EnvironmentObject
. - When to use
@EnvironmentObject
.
Prerequisites
To follow along this tutorial, you’ll need some basic knowledge in:
- A basic familiarity with Swift.
- At least Xcode 11
When to use @EnvironmentObject
Given a scenario where view A create an object and place it inside the environment, any views inside should be able to gain access to that object whenever they need it. This will save a lot of trouble from passing from screen to screen.

However, there is a downfall if not properly configured. When you have declare @EnvironmentObject
in your code, SwiftUI will then automatically locate for the object and when it is not found, your app will crash immediately.
Do take note that when you use @EnvironmentObject
, you are essentially saying that there is an object exists and you should always make sure that there is.
How to use @EnvironmentObject
With @EnvironmentObject
, SwiftUI allows you to share the all across yours views in your app. Sound a lot like Singleton to me, but it isn’t.
A more practical use of @EnvironmentObject
where a user moves from View A to View B then to View C and then View D with information passed from screen to screen. Instead of passing from screen to screen, View A could just pass the data to the environment and then you could then retrieve the data from the environment in View D. Your code will look even tidier this way.
You are building an app where you would like to know if the dark mode is toggled or not. You first create an ObservableObject
1 2 3 |
class DeviceSetting: ObservableObject { @Published var isDarkMode = false } |
Next, inside SceneDelegate
, initialise DeviceSetting
1 |
var deviceSetting = DeviceSetting() |
And connect it with your ContentView
as followed:
1 |
let contentView = ContentView().environmentObject(deviceSetting) |
The first screen that you will be working on is ContentView
, this is kinda like your home page.
Here you will be able to toggle the dark mode to your desire.
1 2 3 4 5 6 7 8 9 10 11 12 |
@EnvironmentObject var deviceSetting: DeviceSetting var body: some View { NavigationView { VStack { Toggle("Toggle Dark Mode", isOn: $deviceSetting.isDarkMode) NavigationLink(destination: DetailView()) { Text("Detail Screen") }.navigationBarTitle("Home") }.padding() } } |

Next screen is the Detail Screen, where you will be able to the state of the dark mode.
1 2 3 4 5 6 7 8 |
@EnvironmentObject var deviceSetting: DeviceSetting var body: some View { HStack { Text("Dark Mode is") self.deviceSetting.isDarkMode ? Text("Enabled") : Text("Disabled") }.navigationTitle("Setting Screen") } |
See it in action how this is being done.

Where to go From Here
Feel like SwiftUI is something that you will really like and want to explore more? Check out my page where you can learn how to use most of the components in SwiftUI.
Not enough explanation for why the @environmentObject is different with Singleton. Now I still feel these are the same purpose…