@EnvironmentObject란?

2024. 9. 22. 18:57·Category/iOS
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 방식과 잘 어울리는 방식으로 앱의 전역 상태를 관리할 수 있습니다.

728x90

'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
'Category/iOS' 카테고리의 다른 글
  • @FocusState란?
  • Identifiable이란?
  • NavigationStack이란?
  • ZStack이란?
Corinee
Corinee
  • Corinee
    Coding Note
    Corinee
  • 전체
    오늘
    어제
    • 분류 전체보기 (361) N
      • Category (354)
        • Algorithm (7)
        • SQL (2)
        • Java (4)
        • C (9)
        • React (7)
        • JavaScript (9)
        • CSS (2)
        • Node (1)
        • SpringBoot (26)
        • Database (3)
        • Network (1)
        • Django (6)
        • Python (22)
        • Flask (4)
        • iOS (25)
        • Swift (4)
        • Flutter (11)
        • Dart (3)
        • Git (1)
        • Firebase (1)
        • Gof (1)
        • 정보처리기사 (112)
        • AI (5)
        • NestJs (4)
        • Docker (1)
        • 사이드 프로젝트 (1)
        • Note (80)
        • Socket (1)
        • 개인 정보 처리 방침 (1)
        • 면접 (0)
        • Vue.js (0)
      • Archive (2) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    소프트웨어 버전 관리
    jackson 라이브러리
    mcp server
    react
    mermaid-cli
    x.y.z (메이저.마이너.패치)
    named export vs default export
    useEffect
    counter
    math.h
    defaultdict
    public vs assets
    structuredclone()
    중첩 함수(nested function)
    react router
    ajax (asynchronous javascript and xml)
    styled-components
    Collections
    원시값(primitive)
    inp
    프로세스 강제 종료
    json.parse(json.stringify())
    chrome extension 자동 배포
    core web vitals
    쉽게 풀어쓴 C언어 Express
    Jest
    stdlib.h
    semver)
    시맨틱 버전(semantic versioning
    intellij 콘솔 한글 깨짐
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
Corinee
@EnvironmentObject란?
상단으로

티스토리툴바