본문 바로가기
Category/iOS

@EnvironmentObject란?

by Corinee 2024. 9. 22.
728x90
반응형

@EnvironmentObject는 SwiftUI에서 뷰 간에 데이터를 공유하는 방법 중 하나로, 전역 상태 관리에 주로 사용됩니다. 이는 뷰의 계층 구조를 따라 상위 뷰에서 하위 뷰로 데이터를 전달하는 방식이며, 상위에서 설정된 객체를 하위에서 자동으로 사용할 수 있게 합니다.

@EnvironmentObject는 앱의 여러 뷰에서 공유되는 데이터를 관리할 때 매우 유용합니다. 예를 들어, 앱 전체에서 상태를 유지해야 하는 사용자 설정이나 세션 정보 등을 공유할 때 사용됩니다.

1. 기본 개념

  • 전역 상태 관리: @EnvironmentObject는 앱의 여러 뷰 간에 전역적으로 상태를 공유하고, 이 상태가 변경될 때 관련된 모든 뷰를 자동으로 업데이트합니다.
  • ObservableObject와 연동: @EnvironmentObject는 내부적으로 ObservableObject와 함께 사용됩니다. 즉, @EnvironmentObject로 지정된 객체는 ObservableObject로 선언되어야 합니다.

2. 사용 방법

  1. ObservableObject 클래스 정의: 먼저 ObservableObject 프로토콜을 채택한 클래스를 정의하고, 해당 클래스의 속성을 @Published로 선언하여 상태 변화를 감지할 수 있게 합니다.
  2. 상위 뷰에서 environmentObject(_:)로 객체를 주입: @EnvironmentObject는 상위 뷰에서 environmentObject(_:)를 통해 주입된 후, 하위 뷰에서 사용할 수 있습니다.
  3. 하위 뷰에서 @EnvironmentObject로 객체를 참조: 하위 뷰에서는 @EnvironmentObject로 선언된 속성을 통해 해당 객체에 접근합니다.

3. 예시

1) ObservableObject 클래스 정의

class UserSettings: ObservableObject {
    @Published var username: String = "Guest"
}

여기서 UserSettings는 사용자의 설정을 관리하는 클래스입니다. username 속성은 @Published로 선언되어 있어, 값이 변경되면 이를 사용하는 모든 뷰가 업데이트됩니다.

2) 상위 뷰에서 환경 객체 설정

struct ContentView: View {
    @StateObject private var userSettings = UserSettings()
    
    var body: some View {
        NavigationStack {
            VStack {
                Text("Current user: \(userSettings.username)")
                NavigationLink("Go to Detail View") {
                    DetailView()
                }
            }
        }
        .environmentObject(userSettings)  // 환경 객체 설정
    }
}
  • @StateObject로 UserSettings 객체를 생성하고, 이 객체를 environmentObject(_:)를 통해 하위 뷰에 전달합니다.
  • environmentObject를 통해 전달된 객체는 하위 뷰에서 자동으로 사용할 수 있습니다.

3) 하위 뷰에서 @EnvironmentObject로 참조

struct DetailView: View {
    @EnvironmentObject var userSettings: UserSettings
    
    var body: some View {
        VStack {
            Text("User: \(userSettings.username)")
            
            Button("Change Username") {
                userSettings.username = "SwiftUI User"
            }
        }
    }
}
  • @EnvironmentObject를 통해 상위 뷰에서 전달된 객체에 접근할 수 있습니다.
  • 버튼을 눌러 username을 변경하면, 상위 뷰와 하위 뷰 모두 자동으로 업데이트됩니다.

동작 설명

  • ContentView에서 userSettings 객체를 환경 객체로 설정하면, DetailView에서 @EnvironmentObject로 해당 객체를 자동으로 사용할 수 있습니다.
  • DetailView에서 username이 변경되면, ContentView에서 이를 사용하고 있는 Text 뷰도 자동으로 업데이트됩니다.

4. @StateObject vs @EnvironmentObject vs @ObservedObject

@StateObject 뷰에서 새로운 객체를 생성하고, 해당 뷰에서만 상태를 관리할 때 사용합니다. 뷰의 라이프사이클과 함께 객체가 유지됩니다. 뷰에서 직접 관리하는 상태가 필요할 때
@ObservedObject 외부에서 전달된 객체를 관찰하고, 상태 변경 시 UI를 업데이트합니다. 객체를 소유하지 않고 참조만 합니다. 객체가 외부에서 전달되고, 해당 객체의 상태를 참조하고 싶을 때
@EnvironmentObject 상위 뷰에서 전역적으로 주입된 상태를 하위 뷰에서 참조하고, 해당 상태가 변경되면 UI를 업데이트합니다. 여러 뷰에서 전역적으로 상태를 공유하고 싶을 때

5. 사용 시 주의사항

  • 상위 뷰에서 반드시 environmentObject(_:)로 객체를 주입해야 합니다. 그렇지 않으면, 하위 뷰에서 @EnvironmentObject로 해당 객체를 참조할 때 앱이 크래시될 수 있습니다.
  • @EnvironmentObject는 뷰 계층 구조에서 데이터를 전파하는 방식이기 때문에, 너무 많은 데이터를 EnvironmentObject로 관리하면 성능 저하나 복잡한 상태 관리 문제가 발생할 수 있습니다.

6. @EnvironmentObject의 장점

  • 전역적인 상태 관리: 여러 뷰 간에 상태를 쉽게 공유할 수 있습니다. 상태를 한 번 설정하면, 뷰 계층 구조 전체에서 재사용할 수 있어 전역 상태 관리에 적합합니다.
  • 간결한 데이터 전파: 부모 뷰에서 자식 뷰로 데이터를 명시적으로 전달할 필요 없이, 부모 뷰에서 설정된 객체를 자식 뷰들이 자연스럽게 참조할 수 있습니다.
  • 자동 UI 업데이트: ObservableObject의 @Published 속성과 함께 사용하면, 상태가 변경될 때 SwiftUI가 자동으로 UI를 업데이트해 줍니다.

결론

@EnvironmentObject는 전역적으로 상태를 관리하고 여러 뷰 간에 데이터를 공유할 때 매우 유용한 도구입니다. SwiftUI에서 앱 전체 또는 큰 뷰 계층에서 데이터를 쉽게 전달하고 관리할 수 있으며, 상태 변화에 따라 UI가 자동으로 업데이트되는 편리함을 제공합니다.

이 개념을 활용하면 복잡한 상태 관리를 더 효율적으로 처리할 수 있으며, SwiftUI의 선언적 UI 방식과 잘 어울리는 방식으로 앱의 전역 상태를 관리할 수 있습니다.

'Category > iOS' 카테고리의 다른 글

@FocusState란?  (0) 2024.09.23
Identifiable이란?  (0) 2024.09.22
NavigationStack이란?  (1) 2024.09.22
ZStack이란?  (0) 2024.09.22
enum(열거형)이란?  (1) 2024.09.22