본문 바로가기

iOS 관련 공부/SwiftUI

SwiftUI - Environment, Property Wrapper

Environment

SwiftUI에서 Environment 라는 것은 Property Wrapper 라는 특수한 형태의 구조이다.

Environment는 뷰 계층(View Hierarchy) 전체에 걸쳐 데이터와 설정 값을 공유할 수 있도록 해주는 강력한 도구이다.

주로 앱의 전역 상태, 시스템 설정(예: 다크모드, 지역화, 접근성 등) 또는 외부에서 주입해야 하는 값(예: Core Data의 managedObjectContext)을 하위 뷰에 전달할 때 사용한다.

 

Environment의 주요 개념

  • Environment란?
    • 부모 뷰가 정의한 값을 자식 뷰가 참조할 수 있게 하는 컨텍스트이다.
    • 예를 들어, colorScheme(다크/라이트 모드), locale(지역화), 접근성 설정 등 앱의 전역 상태 정보를 뷰 계층에서 쉽게 전달할 수 있다.
  • @Environment 속성 래퍼
    • SwiftUI에서 환경 값을 읽기 위해 사용하는 Property Wrapper이다.
    • 예시: @Environment(\.colorScheme) var colorScheme
      이 코드는 현재 뷰에서 시스템의 다크/라이트 모드 정보를 읽어온다.
    • 환경 값은 읽기 전용이며, 직접 수정할 수 없다.
  • Environment 값의 주입과 사용
    • 상위 뷰에서 .environment(_ keyPath:, _ value:) 메서드를 사용해 환경 값을 지정할 수 있다
    • 하위 뷰에서는 @Environment 를 통해 해당 값을 읽어올 수 있다.
    • 예시:
// 상위 뷰에서 환경 값 주입
ContentView()
  .environment(\.managedObjectContext, persistentController.container.viewContext)

// 하위 뷰에서 환경 값 사용
struct ContentView: View {
  @Environment(\.managedObjectContext) var context
  ...
}

이처럼 Core Data의 managedObjectContext를 환경에 주입하면, 하위 뷰 어디서든 쉽게 꺼내쓸 수 있다.

  • 자동 전파
    • 환경 값은 부모 뷰에서 자식 뷰로 자동 전파된다.
    • 예를 들어, disabeled(_:) 수정자를 사용하면 해당 뷰와 모든 하위 뷰에 비활성화 상태가 전파되고, 자식 뷰에서는 @Environment(\.isEnabled) 로 부모의 상태를 참조할 수 있다.

 

Environment의 장점

  • 뷰 간의 의존성을 줄이고, 코드의 가독성과 재사용성을 높일 수 있다.
  • 전역 상태나 시스템 설정을 뷰 계층 전체에 쉽게 전달할 수 있다.
  • 외부에서 주입해야 하는 값(예: Core Data context, 사용자 정의 값 등)을 뷰 계층 전체에 손쉽게 공유할 수 있다.

 

요약

  • Environment는 SwiftUI에서 뷰 계층 전체에 데이터와 설정 값을 공유하는 컨텍스트이다.
  • @Environment 속성 래퍼를 사용해 환경 값을 읽을 수 있으며, 상위 뷰에서 .environment() 로 값을 주입한다.
  • 시스템 제공 값(colorScheme, locale 등)과 커스텀 값 모두 지원한다.
  • 환경 값은 부모에서 자식 뷰로 자동 전파되어, 뷰 간 데이터 전달이 매우 간편해진다.

 

 

 

그렇다면,,,

Property Wrapper란?!

Property Wrapper는 Swift 5.1에서 도입된 기능으로, 프로퍼티의 저장 방식과 접근 방식을 별도의 타입으로 분리해 관리할 수 있게 해주는 문법이다. 쉽게 말해, 프로퍼티를 한 번 감싸서(래핑해서) 공통된 로직을 재사용할 수 있도록 해준다.

 

 

Property Wrapper의 핵심 개념

  • 정의
    Property Wrapper는 구조체(struct), 클래스(class), 열거형(enum)에서 사용 가능한 특별한 타입이다.
    @propertyWrapper 라는 어노테이션을 붙여 정의하며, 내부에 반드시 wrappedValue 라는 프로퍼티를 포함해야 한다.
  • 동작 방식
    Property Wrapper를 사용하면,
    • 프로퍼티의 저장/관리 로직(예: 값의 유효성 검사, 변환, 제한 등)과
    • 프로퍼티를 선언하는 코드
      이 둘을 분리할 수 있다.
  • 사용 목적
    • 반복되는 get/set 로직을 한 번만 정의하고 여러 프로퍼티에서 재사용할 수 있다.
    • 코드의 중복을 줄이고, 선언부를 간결하게 만든다.

예시

@propertyWrapper
struct Uppercased {
    private var value: String = ""
    var wrappedValue: String {
        get { value.uppercased() }
        set { value = newValue }
    }
}

struct Person {
    @Uppercased var name: String
}

var p = Person()
p.name = "swift"
print(p.name) // "SWIFT"

위 예시에서 @Uppercased 는 name 프로퍼티에 항상 대문자만 저장되도록 래핑해준다.

 

 

SwiftUI에서의 활용

SwiftUI에서 자주 사용하는 @State, @Biding, @ObservedObject, @Environment 등도 모두 Property Wrapper 로 구현되어 있다. 이들은 뷰의 상태 관리, 데이터 바인딩, 환경 값 주입 등 다양한 역할을 담당한다.

 

 

정리

  • Property Wrapper는 프로퍼티의 저장/관리 로직을 별도의 타입으로 분리해 재사용성을 높여주는 Swift의 문법이다.
  • 반복되는 코드를 줄이고, 선언부를 간결하게 만들어준다.
  • SwiftUI의 다양한 상태 관리 기능도 Property Wrapper를 기반으로 동작한다.

'iOS 관련 공부 > SwiftUI' 카테고리의 다른 글

SwiftData 기본적인 내용..이라고 해야할까..?  (0) 2025.04.18
네비게이션바 라지타이틀 없애버리기...  (0) 2025.04.17
SwiftUI - LazyStack  (0) 2025.04.17
SwiftUI - stack views  (0) 2025.04.16
SwiftUI - Navigation  (0) 2025.04.16