— SwiftUI, EnvironmentObject, Data sharing — 2 min read
SwiftUI provides several ways to share data between views, and one of the most powerful mechanisms is through the use of the @EnvironmentObject
property wrapper. With this tool, you can create a single source of truth for your data, which can be accessed and modified by any SwiftUI view that needs it. In this post, we will explore how to use @EnvironmentObject
to share data between SwiftUI views in a clean and efficient manner.
First, let's define a class that will hold the data we want to share. This class needs to conform to the ObservableObject
protocol, and its properties need to have the @Published
property wrapper in order to trigger updates to any views that use them. Here's an example:
1class UserData: ObservableObject {2 @Published var name = "John Doe"3 @Published var age = 304}
In this case, we have defined a simple UserData
class with two properties: name
and age
. Both are marked with @Published
, which means that any changes made to them will trigger updates to any views that use them.
Next, we need to create an instance of UserData
and make it available to our views(or inject it I guess?) through the use of the @EnvironmentObject
property wrapper. We can do this in the SceneDelegate
or AppDelegate
depending on our app's architecture:
1let userData = UserData()2
3~~~4
5ContentView()6 .environmentObject(userData)
Here we have created an instance of UserData
and passed it to the ContentView
using the environmentObject(_:)
modifier. From this point on, any view that needs to access UserData
can simply declare it as an @EnvironmentObject
property.
To access an @EnvironmentObject
property, you simply declare it as a property in your view. For example, if we wanted to display the user's name and age in a Text
view, we could do something like this:
1struct ProfileView: View {2 @EnvironmentObject var userData: UserData3 4 var body: some View {5 VStack {6 Text("Name: \(userData.name)")7 Text("Age: \(userData.age)")8 }9 }10}
In this case, we have declared userData
as an @EnvironmentObject
property and used it to display the user's name and age in two separate Text
views. Because userData
is marked with @Published
, any changes made to it will automatically trigger updates to this view.
Finally, let's take a look at how we can modify an @EnvironmentObject
property. To do this, we simply call a method on the object that changes its state. For example, if we wanted to change the user's name, we could do something like this:
1Button("Change Name") {2 userData.name = "Jane Doe"3}
This will update the name
property of our UserData
instance, which will trigger updates to any views that use it. This means that if we have a ProfileView
open while we tap this button, the Text
view displaying the user's name will automatically update to show the new value.
In this post, we've seen how to use @EnvironmentObject
to share data between SwiftUI views. By defining an ObservableObject
and making it available as an environment object, we can create a single source of truth for our data and make it easily accessible to any view that needs it. We can also modify this data in a clean and efficient manner, using the @Published
property wrapper to trigger updates to our views.
SwiftUI provides many tools for data sharing, but @EnvironmentObject
is one of the most powerful and flexible mechanisms available. By using it effectively, we can create clean, well-organized SwiftUI code that is easy to understand and maintain.