@Environment Object | SwiftUI
What is @Environment Object
SwiftUI’s @EnvironmentObject
property wrapper lets us create views that rely on shared data, often across an entire SwiftUI app. For example, if you create a user that will be shared across many parts of your app, you should use @EnvironmentObject
.
By using @EnvironmentObject
we’re saying that value will be provided by the SwiftUI environment rather than explicitly created by the view. If one view changes the object all other views automatically get updated
If you are unsure which property wrapper to choose in any situation, checkout the link below:
Warning: When a view using @EnvironmentObject
is shown, SwiftUI will immediately search the environment for an object of the correct type. If such an object can’t be found – i.e., if you forgot to place it in the environment – then your app will immediately crash. When you use @EnvironmentObject
you are effectively promising that object will exist in the environment by the time it is needed, a bit like using implicitly unwrapped optionals.
@EnvironmentObject Example:
struct ContentView: View {
var prospects = Prospects()
var body: some View {
TabView {
ProspectsView(filter: .none)
.tabItem {
Image(systemName: "person.3")
Text("Everyone")
}
ProspectsView(filter: .contacted)
.tabItem {
Image(systemName: "checkmark.circle")
Text("Contacted")
}
ProspectsView(filter: .uncontacted)
.tabItem {
Image(systemName: "questionmark.diamond")
Text("Uncontacted")
}
}
.environmentObject(prospects)
}
}
struct ProspectsView: View {
enum FilterType {
case none, contacted, uncontacted
}
@EnvironmentObject var prospects: Prospects
let filter: FilterType
var title: String {
switch filter {
case .none:
return "Everyone"
case .contacted:
return "Contacted people"
case .uncontacted:
return "Uncontacted people"
}
}
var body: some View {
NavigationView {
Text("People: \(prospects.people.count)")
.navigationBarTitle(title)
.navigationBarItems(trailing: Button(action: {
let prospect = Prospect()
prospect.name = "Paul Hudson"
prospect.emailAddress = "paul@hackingwithswift.com"
self.prospects.people.append(prospect)
}) {
Image(systemName: "qrcode.viewfinder")
Text("Scan")
})
}
}
}
class Prospect: Identifiable, Codable {
var id = UUID()
var name = "Anonymous"
var emailAddress = ""
var isContacted = false
}
class Prospects: ObservableObject {
@Published var people: [Prospect]
init() {
self.people = []
}
}