@Environment variables
Tags: environment, swiftui
Published: 2024-07-10 06:13:09

---
title: @Environment variables
published: true
date: 2024-07-08 19:25:27 UTC
tags: Environment,SwiftUI
canonical_url: https://wesleydegroot.nl/blog/@Environment
---

SwiftUI provides a way to pass data down the view hierarchy using `@Environment` variables. These variables are environment-dependent and can be accessed from any child view. They are useful for sharing common data or settings across the app, such as color schemes, locale, or accessibility settings.

When you create an `@Environment` variable, SwiftUI automatically manages its value for you. This means that when the environment changes, the view will automatically update to reflect the new value.

## Creating an @Environment Variable

To create an `@Environment` variable, you can use one of the built-in environment keys provided by SwiftUI, such as `.colorScheme`, `.locale`, or `.accessibilityEnabled`. For example, to access the color scheme environment variable, you can use the following code:

```swift
struct ContentView: View {
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        Text("Hello, World!")
            .foregroundColor(colorScheme == .dark ? .white : .black)
    }
}
```

In this example, the `colorScheme` variable is an `@Environment` variable that holds the current color scheme of the app. The text color is set based on the color scheme (dark or light) using a ternary operator.

## Custom @Environment Variables

You can also create custom `@Environment` variables to pass custom data or settings down the view hierarchy. To define a custom `@Environment` variable, you need to create a new type that conforms to the `EnvironmentKey` protocol and extend `EnvironmentValues` to introduce the value.

Here's an example of how you can define a custom `@Environment` variable:

```swift
private struct MyCustomKey: EnvironmentKey {
    // Create a default value for the custom environment key
    static let defaultValue: String = "Default Value"
}

extension EnvironmentValues {
    /// Define a custom environment variable
    var myCustomValue: String {
        get { self[MyCustomKey.self] }
        set { self[MyCustomKey.self] = newValue }
    }
}
```

In this example, we define a custom key `MyCustomKey` that holds a default string value. We then extend `EnvironmentValues` to introduce the custom value `myCustomValue` using the key.

You can now use the custom `@Environment` variable in your views like this:

```swift
/// Pass custom environment value
struct ContentView: View {
    var body: some View {
        VStack {
            SecondView()
                .environment(\.myCustomValue, "hello there")
        }
    }
}

/// Access custom environment value
struct SecondView: View {
    @Environment(\.myCustomValue) var customValue

    var body: some View {
        Text(customValue)
    }
}
```

In this example, the `customValue` variable is an `@Environment` variable that holds the custom value defined earlier. The text view displays the value of the custom environment variable.

## iOS 18 and later (easier)

```swift
/// Setup environment key
extension EnvironmentValues {
    @Entry var myCustomValue: String = "Default Value"
}

/// Pass custom environment value
struct ContentView: View {
    var body: some View {
        VStack {
            SecondView()
                .environment(\.myCustomValue, "hello there")
        }
    }
}

/// Access custom environment value
struct SecondView: View {
    @Environment(\.myCustomValue) var customValue

    var body: some View {
        Text(customValue)
    }
}
```

## Caveats

When using `@Environment` variables, keep in mind that they are not meant for sharing complex data structures or models across the view hierarchy. For more complex data sharing, consider using `@EnvironmentObject` or other data sharing techniques.

## Wrap up

`@Environment` variables are a powerful tool in SwiftUI for sharing common data or settings across the app. By creating custom `@Environment` variables, you can extend this functionality to suit your app's specific needs. Just remember to use them judiciously and follow best practices to avoid potential pitfalls.

Resources:

- [SwiftUI Environment](https://developer.apple.com/documentation/swiftui/environment)