← 메인으로

0817-1 Environment 객체

구독되는 객체는 특정 상태가 앱 내의 몇몇 SwiftUI 뷰에 의해 사용되어야 할 경우에 가장 적합하다. 그런데, 어떤 뷰에서 다른 뷰로 이동(navigation)하는 데 이동될 뷰에서도 동일한 구독 객체에 접근해야 한다면, 이동할 때 대상 뷰로 구독되는 객체에 대한 참조를 전달해야 할 것이다.

@StateObject var demoData : DemoData = DemoData() NavigationLink(destination: SecondView(demoData)) { Text("Next Screen") } 

Environment 객체는 Observable 객체와 같은 방식으로 선언된다. 즉, 반드시 ObservableObject 프로토콜을 따라야 하며, 적절한 프로퍼티가 게시되어야 한다. 하지만, 중요한 차이점은 이 객체는 SwiftUI 환경에 저장되며, 뷰에서 뷰로 전달할 필요 없이 모든 자식 뷰가 접근할 수 있다는 것이다. 다음의 Observable 객체 선언 예제를 살펴보자.

class SpeedSetting: ObservableObject { @Published var speed = 0.0 } 
struct SpeedControlView: View { @EnvironmentObject var speedSetting: SpeedSetting var body: some View { Slider(value: @speedSetting.speed, in: 0...100) } } struct SpeedDisplayView: View { @EnvironmentObject var speedSetting: SpeedSetting var body: some View { Text("Speed = \(speedSetting.speed)") } } 
struct ContentView: View { let speedsetting = SpeedSetting() var body: some View { VStack { SpeedControlView() SpeedDisplayView() } } } 
struct ContentView: View { let speedsetting = SpeedSetting() var body: some View { VStack { SpeedControlView() SpeedDisplayView() } .environmentObject(speedsetting) } } 

요약

SwiftUI는 사용자 인터페이스와 앱의 로직에 데이터를 바인딩하는 방법 세 가지를 제공한다. 상태 프로퍼티는 사용자 인터페이스 레이아웃 내의 뷰 상태를 저장하는 데 사용되며, 현재 콘텐트 뷰에 관한 것이다. 이 값은 임시적이어서 해당 뷰가 사라지면 값도 없어진다.

사용자 인터페이스 밖에 있으며 앱 내의 SwiftUI 뷰 구조체의 하위 뷰에만 필요한 데이터는 Observable 객체 프로퍼티를 사용해야 한다. 이 방법을 사용하면 데이터를 표시하는 클래스나 구조체는 ObservableObject 프로토콜을 따라야 하며, 뷰와 바인딩될 프로퍼티는 @Published 프로퍼티 래퍼를 사용하여 선언되어야 한다.

뷰 선언부에 Observable 객체 프로퍼티와 바인딩하려면 프로퍼티는 @ObservedObject 또는 @StateObject 프로퍼티를 사용해야 한다.(대부분의 경우 @StateObject가 선호)

사용자 인터페이스 밖에 있으며 여러 뷰가 접근해야 하는 데이터일 경우에는 Environment 객체가 최고의 해결책이 된다. Observable 객체와 동일한 방법으로 선언되지만, Environment 객체 바인딩은 @EnvironmentObject 프로퍼티 래퍼를 사용하여 SwiftUI 뷰 파일 내에 선언된다. 자식 뷰에 접근할 수 있게 되기 전에 environmentObject() 수정자를 사용하여 뷰 계층 구조에 삽입하기 전에 Environment 객체도 초기화해야 한다.

[!note] 굉장히 중요한 부분인데 흐름이 자꾸 끊기다보니 이해가 잘 안된다. 이해가 되다가 끊긴 느낌? 확실히 짚고 이해하고 넘어가야 할 것 같다.