The @Entry macro declares a custom environment value in one line, replacing the
EnvironmentKey type plus the getter and setter extension. It also works for focused, container,
and transaction values, and it back-deploys to earlier OS versions.
Before and After
The manual pattern needs a key type with a defaultValue and a computed property on
EnvironmentValues, repeated for every value you share.
struct UserStateEnvironmentKey: EnvironmentKey {
static var defaultValue: UserState = .new
}
extension EnvironmentValues {
public var userState: UserState {
get { self[UserStateEnvironmentKey.self] }
set { self[UserStateEnvironmentKey.self] = newValue }
}
}
With the macro, the default value comes from the initializer:
extension EnvironmentValues {
@Entry var userState = UserState.new
}
Using the Value
The macro generates the key path, so injection and reading look exactly like any built-in environment value.
@main
struct MyApp: App {
@State var userState = UserState.new
var body: some Scene {
WindowGroup {
ContentView()
.environment(\.userState, userState)
}
}
}
Focused Values
The same macro replaces FocusedValueKey boilerplate. The one difference: the property must be
optional, because a focused value only exists while a view is focused.
extension FocusedValues {
@Entry var noteValue: String?
}