SwiftUI에서 @Environment — 정의, 핵심 개념 및 메커니즘

저자: IT Sectr 게시일: 2026-06-25 읽는 시간: 8 분

SwiftUI에서 @Environment는 시스템 환경에서 값을 읽는 페이지 그림과 같이 View 계층 구조를 통해 자동으로 분포되는 property wrapper입니다. 이 컴포넌트는 색상 체계, 로케일, 폰트 크기, managedObjectContext 및 수십 개의 다른 시스템 매개변수에 액세스를 제공합니다. Apple Developer Documentation (2025)에 따르면, @Environment는 환경 값의 변경이 구독한 모든 View의 재그림을 유발하여 수동 호출 없이 반응형 인터페이스 업데이트를 제공함을 보장합니다.

주요 포인트

  • @Environment — SwiftUI 시스템 환경 값을 읽기 위한 property wrapper
  • 색상 체계, 로케일, 폰트 크기는 일반적으로 사용되는 시스템 값
  • 변경은 구독한 View의 자동 재그림을 유발
  • 커스텀 키를 통해 EnvironmentKey로 직접 환경 값 생성 가능
  • @Environment — 읽기 전용; @EnvironmentObject — 쓰기 용

SwiftUI에서 @Environment이란?

@Environment는 시스템 환경에서 값을 읽도록 설계된 SwiftUI property wrapper입니다. 환경은 SwiftUI가 부모 View에서 자식 View로 자동 분배하는 값의 계층 컨테이너입니다. 각 환경 값은 EnvironmentKey 프로토콜에 따르는 타입인 키로 식별됩니다.

환경 메커니즘은 프레임워크 레벨의 의존성 주입(dependency injection)과 유사합니다: 시스템은 미리 정의된 값의 셋을 제공합니다 — 색상 체계(밝음/어두움), 로케일, 폰트 크기, Core Data용 managedObjectContext, 화면을 닫기 위한 dismiss, 그리고 많은 다른 것들. 특정 키를 가진 @Environment를 선언한 View는 자동으로 현재 값을 받고 변경시 재그림됩니다.

SwiftUI 환경 아키텍처는 EnvironmentValues 프로토콜에 기반합니다 — 모든 시스템 값을 포함하는 구조체입니다. 각 값은 getter와 setter가 있는 이 구조체의 포함된 속성으로 저장됩니다. @Environment는 특정 속성에 액세스하기 위해 key path를 사용합니다: @Environment(\.colorScheme) — 색상 체계 액세스, @Environment(\.locale) — 로케일 액세스.

Property Wrapper로서의 @Environment

Property wrapper @Environment는 두 가지 핵심 메커니즔을 구현합니다: 환경에서 값을 읽고 그 변경에 구독하는 것입니다. View가 생성되면 SwiftUI는 모든 @Environment 속성을 통해 현재 컨텍스트의 해당 값과 연결합니다. 부모 View가 .environment() 수식자를 통해 값을 변경하면, 해당 값을 읽는 모든 자식 View가 자동으로 재그림됩니다.

중요한 기능: @Environment는 옵션변수 값을 지원합니다. 계층에서 값이 설정되지 않았으면 EnvironmentKey에 정의된 기본값이 반환됩니다. 시스템 키의 경우 기본값은 허수 적절합니다 — 예를 들어, 기본 색상 체계는 .light입니다. 커스텀 키의 경우, 개발자는 EnvironmentKey 프로토콜의 defaultValue 메서드에서 기본값을 정의합니다.

swift
struct EnvironmentReaderView: View {
    @Environment(\.colorScheme) var colorScheme
    @Environment(\.locale) var locale
    @Environment(\.sizeCategory) var sizeCategory

    var body: some View {
        VStack {
            Text("Current scheme: \(colorScheme == .dark ? "Dark" : "Light")")
            Text("Locale: \(locale.identifier)")
            Text("Font size: \(sizeCategory)")
        }
    }
}

예시에서 View는 세 가지 시스템 환경 값을 읽습니다. colorScheme이 변경될 때 — 예를 들어, 사용자가 설정에서 어두운 모드를 활성화했을 때 — View는 새 값으로 자동 재그림됩니다. 같은 방식으로 지역 또는 폰트 크기(Dynamic Type)가 변경될 때도 마찌가지입니다. View는 알림에 구독하거나 refresh를 호출할 필요가 없습니다 — SwiftUI가 이를 자동으로 관리합니다.

시스템 환경 값

SwiftUI는 인터페이스와 동작의 다양한 측면을 다루는 수십 개의 시스템 환경 값을 제공합니다. 색상 체계 (\.colorScheme)는 가장 많이 사용되는 값 중 하나로, 밝은 맞고 어두운 테마에 맞게 인터페이스를 조절할 수 있게 합니다. 로케일 (\.locale)에는 날짜, 숫자 및 통화 포맷을 위한 사용자의 지역 설정이 포함됩니다.

Core Data의 경우, managedObjectContext (\.managedObjectContext)가 사용됩니다 — 퍼시스티스 커네이너에서 환경을 통해 전달되는 컨텍스트입니다. 네비게이션의 경우, 현재 화면을 닫기 위한 dismiss (\.dismiss) 및 모달 표시를 위한 isPresented (\.isPresented)가 제공됩니다. 캘린더와 시간대의 경우 — 각각 calendar와 timeZone이 있습니다.

Key Path타입목적
\.colorSchemeColorScheme밝은/어두운 테마
\.localeLocale지역 설정
\.sizeCategoryContentSizeCategoryDynamic Type 폰트 크기
\.managedObjectContextNSManagedObjectContextCore Data 컨텍스트
\.dismissDismissAction화면 닫기
\.calendarCalendar현재 캘린더
\.timeZoneTimeZone시간대
\.horizontalSizeClassUserInterfaceSizeClass가로 화면 크기

시스템 값에 액세스하려면 점이 든 key path를 사용하세요: @Environment(\.dismiss) var dismiss. 컴파일러는 EnvironmentValues에서 key path의 존재를 확인하뭐로, 올바르지 않은 키는 컴파일 타임 오류를 유발합니다. Apple은 iOS 버전마다 새로운 시스템 값을 추가합니다 — 전체 목록은 EnvironmentValues 문서에서 확인할 수 있습니다.

@Environment vs @EnvironmentObject

비슷한 이름에도 불구하고, @Environment@EnvironmentObject는 서로 다른 목적을 가집니다. @Environment는 EnvironmentKey를 통해 등록된 시스템 또는 커스텀 값을 읽습니다. @EnvironmentObject는 명시적인 키 없이 타입에 의해 환경을 통해 전달되는 ObservableObject용 property wrapper입니다.

@EnvironmentObject는 의존성 주입(dependency injection)에 사용됩니다: 부모 View가 객체(예: ViewModel)를 생성하고 .environmentObject() 수식자를 통해 자식 View에 전달합니다. 자식 View는 @EnvironmentObject를 통해 이를 수신하고 그 속성을 읽거나 수정할 수 있습니다. 반면, @Environment는 시스템 값에 대해 읽기 전용이며 피드백을 지원하지 않습니다.

매개변수@Environment@EnvironmentObject
목적시스템 및 커스텀 값ObservableObject 주입
EnvironmentValues key path객체 타입에 따라
쓰기읽기 전용읽기 및 쓰기
커스텀 값EnvironmentKey를 통해ObservableObject 클래스를 통해
기본값있음 (defaultValue)없음 (전달해야 함)

실제로: 시스템 매개변수(테마, 로케일, 폰트 크기) 및 런타임에 변경되지 않는 커스텀 구성에 액세스하려면 @Environment를 사용하세요. 상태를 자식 컴포넌트에서 수정해야 할 때 View 계층을 통해 ViewModel 또는 서비스를 전달하려면 @EnvironmentObject를 사용하세요.

@Environment 코드 예시

커스텀 환경 값을 만드는 것을 살펴보겠습니다. 이를 위해 EnvironmentKey 프로토콜에 따르는 구조체를 정의하고 EnvironmentValues를 새 속성으로 확장해야 합니다. 이를 통해 props 없이 전체 View 트리에 테마 구성 또는 앱 설정을 전달할 수 있습니다.

swift
struct AppThemeKey: EnvironmentKey {
    static let defaultValue: AppTheme = .system
}

extension EnvironmentValues {
    var appTheme: AppTheme {
        get { self[AppThemeKey.self] }
        set { self[AppThemeKey.self] = newValue }
    }
}

enum AppTheme { case system, light, dark }

EnvironmentKey 프로토콜은 정적 defaultValue 속성의 구현이 필요합니다 — 부모 View가 커스텀 환경을 설정하지 않은 경우 사용될 값입니다. EnvironmentValues를 확장하면 키가 있는 subscript를 사용하여 계산된 속성 appTheme이 추가됩니다. 그 후, 어떤 View든 @Environment(\.appTheme)를 통해 값을 읽을 수 있습니다.

커스텀 키로 @Environment 사용하기

swift
struct ThemedView: View {
    @Environment(\.appTheme) var appTheme
    @Environment(\.colorScheme) var colorScheme

    var body: some View {
        VStack {
            if appTheme == .dark || (appTheme == .system && colorScheme == .dark) {
                Text("Dark mode active")
                    .foregroundStyle(.white)
                    .background(Color.black)
            } else {
                Text("Light mode active")
                    .foregroundStyle(.black)
                    .background(Color.white)
            }
        }
    }
}

struct ContentView: View {
    @State private var selectedTheme = AppTheme.system

    var body: some View {
        ThemedView()
            .environment(\.appTheme, selectedTheme)
    }
}

ThemedView는 두 가지 환경을 읽습니다: 커스텀 appTheme와 시스템 colorScheme. 이 조합은 유연한 테마 구성을 가능하게 합니다: 사용자는 밝은 것, 어두운 것, 또는 시스템 테마를 선택할 수 있습니다. 시스템이 선택된 경우, 값은 iOS 설정에서 테마가 전환될 때 자동으로 변경되는 colorScheme에서 가져옵니다. 부모 View(ContentView)는 .environment() 수식자를 통해 appTheme 값을 설정합니다.

화면을 닫기 위해 dismiss 사용하기

swift
struct ModalView: View {
    @Environment(\.dismiss) var dismiss
    @State private var name = ""

    var body: some View {
        NavigationStack {
            Form {
                TextField("Your name", text: $name)
                Button("Save") { dismiss() }
            }
            .navigationTitle("Edit Profile")
        }
    }
}

이 예시는 dismiss의 실용적인 사용을 보여줍니다 — 환경에서 DismissAction의 인스턴스입니다. 함수로서 dismiss()를 호출하면 모달 화면이 닫히거나 NavigationLink가 돌아갑니다. 유일한 요구사항은 View가 모달로 표시되거나 NavigationStack 내에 있어야 한다는 것입니다. dismiss는 컨텍스트에서 자동으로 결정됩니다: View가 sheet로 열린 경우 — sheet이 닫히고, popover로 열린 경우 — popover가 닫힉니다.

자주 묻는 질문

자식 View에서 @Environment 값을 변경할 수 있나요?

아니요, @Environment는 읽기 전용입니다. 값을 변경하려면 ObservableObject와 함께 @EnvironmentObject 또는 @Binding을 사용하세요. 커스텀 EnvironmentKeys는 확장에서 setter를 가질 수 있지만, 이를 통한 변경은 UI 업데이트를 유발하지 않습니다 — 기술적으로 가능하지만 권장되지 않습니다.

@Environment와 @Binding은 어떻게 다른가요?

@Binding은 진리의 원천(State, StateObject, ObservableObject)과의 양방향 연결을 만듭니다. @Environment는 계층 컨텍스트에서 단방향 읽기입니다. @Binding은 자식 View에 데이터를 전달하는 데 적합하고, @Environment는 시스템 또는 전역 설정에 액세스하는 데 적합합니다.

직접 환경 값을 만들려면 어떻게 하나요?

정적 defaultValue를 가진 EnvironmentKey 프로토콜을 구현하는 구조체를 정의하세요. 그런 다음 subscript[key]를 통한 getter/setter로 속성을 가진 EnvironmentValues를 확장하세요. 등록 후, 읽기에는 @Environment(\.yourKey)를, 설정에는 .environment(\.yourKey, value)를 사용하세요.

SwiftUI에서 사용 가능한 환경 값은 뭐가 있나요?

SwiftUI는 50개 이상의 시스템 값을 제공합니다: colorScheme, locale, sizeCategory, managedObjectContext, dismiss, calendar, timeZone, horizontalSizeClass, verticalSizeClass, accessibilityEnabled, layoutDirection, legibilityWeight 그리고 기타. 전체 목록은 EnvironmentValues 문서에서 확인할 수 있습니다.

@Environment은 Preview에서 작동하나요?

네, @Environment은 Preview에서 작동하지만 기본값이 시뮬레이터와 다른 수 있습니다. Preview에서 테스트하려면 Preview 코드에서 바로 .environment() 수식자를 사용하세요: ThemedView().environment(\.colorScheme, .dark). 이를 통해 다양한 환경 상태를 시각적으로 확인할 수 있습니다.

요약

  • @Environment — key path로 SwiftUI 시스템 환경 값을 읽기 위한 property wrapper
  • 색상 체계, 로케일, 폰트 크기, managedObjectContext가 가장 많이 사용되는 시스템 값
  • 변경 환경 값은 구독한 모든 View의 자동 재그림을 유발
  • 커스텀 EnvironmentKey를 통해 앱 환경을 글로벌 설정으로 확장 가능
  • @Environment — 읽기 전용; @EnvironmentObject — 쓰기 액세스가 있는 ObservableObject용
  • .environment() 수식자는 계층에서 자식 View에 값을 설정
  • 사용 @Environment는 시스템 매개변수용, @EnvironmentObject는 ViewModel 및 서비스용

턴키 방식의 모바일 애플리케이션을 개발해 드립니다

IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.

프로젝트 논의

더 읽어보기