Instead of initializing SwiftUI views with dependencies, SwiftUI also offers other ways for injecting dependencies. This time let’s take a look on EnvironmentKey which defines a key for inserting objects to environment and vise-versa. We need to create a EnvironmentKey, adding an object to environment and then getting the object in SwiftUI view.
Creating EnvironmentKey and extending EnvironmentValues
Example object we use is DependencyManager what in real app can contains loads of dependencies. EnvironmentKey is a protocol in SwiftUI what requires to define associated type and default value. Default value is used when we have not explicitly inserted an instance of DependencyManager to the environment, more about it a little bit later. EnvironmentValues is a struct containing a collection of environment objects. We’ll add a property to EnvironmentValues which later will be used by @Environment property wrapper and also when setting an instance of the object to the environment.
Inserting objects to environment
If we would like to insert a DependencyManager to the Environment, we can use func environment(_ keyPath: WritableKeyPath, _ value: V) -> some View using our DependencyManagerKey and an instance created by us. If we do not insert our own, SwiftUI will use the instance returned by defaultValue when the key is first time accessed.
Getting objects from environment
Objects can be read from the environment using @Environment property wrapper and specifing the EnvironmentKey.
We created an environment key and inserted an object into environment. We looked into how SwiftUI handles default values for environment objects and used @Environment property wrapper for getting the instance from the environment using the created key.
If this was helpful, please let me know on Mastodon@toomasvahter or Twitter @toomasvahter. Feel free to subscribe to RSS feed. Thank you for reading.
One reply on “Injecting dependencies using environment values and keys in SwiftUI”
[…] The next step is that we want to allow SwiftUI view to control what is presented on the screen. For example, let’s add a button to the SwiftUI view which should present a sheet with another SwiftUI view. The button action needs to be able to talk to the flow coordinator, which controls what is presented on the screen. One way to insert the FlowCoordinator into SwiftUI environment is by conforming to ObservableObject and using the environmentObject() view modifier. Alternative is using EnvironmentValues and defining a key. For more information please check Injecting dependencies using environment values and keys in SwiftUI. […]