Many blog posts are responses to my students’ questions, and this one is no different. Often, my students need to build fast prototypes without saving permanent data and want to avoid writing complicated code with Core Data or the newer SwiftData. They frequently ask, “How can we share data across the application without passing it as a parameter to every view?” The answer is to use an EnvironmentObject
.
Definition
First, let’s define the object that we want to share:
struct Event: Identifiable { var id = UUID() var name: String } class Shared: ObservableObject { @Published var events: [Event] = [Event]() }
The shared object will be a class, marked as ObservableObject (allowing us to catch changes), with the events
array being the published property. In this case, we have only one array, but there’s no limit to the number of properties that can be published.
Usage
After defining the class, we need to declare a variable of the shared class using @StateObject
. Then, we pass this variable to the .environmentObject
modifier. These steps are performed in just one view—the root view of any other views that will use the shared object.
struct ContentView: View { @State var isPresented = false @StateObject var shared = Shared() var body: some View { NavigationView { List(shared.events) { event in Text(event.name) }.toolbar { ToolbarItem { Button(action: {isPresented = true}) { Label("Add Event", systemImage: "plus") } } } }.sheet(isPresented: $isPresented, content: { DemoUIView() }).environmentObject(shared) } }
In this scenario, the root view displays a list of events. By tapping on the plus icon, we can add another event.
Any other view that uses (displays or modifies) the shared data simply needs to declare @EnvironmentObject var shared: Shared
. In this case we type the event name and add this event to the events list.
struct DemoUIView: View { @State var name = "" @EnvironmentObject var shared: Shared var body: some View { VStack { TextField("Event Name", text: $name) Button("Save", action: { shared.events.append(Event(name: name)) }) }.padding() } }
Enjoy creating your application.
Note: English is not my native language, so I apologize for any errors. I use AI solely to generate the banner of the post; the content is human-generated.