SwiftUI 데이터 모델링 기법: @ObservedObject, @State, @EnvironmentObject 활용

작성일 :

SwiftUI 데이터 모델링 기법: @ObservedObject, @State, @EnvironmentObject 활용

SwiftUI는 애플이 2019년에 발표한 사용자 인터페이스 프레임워크로, 선언적 문법을 통해 빠르고 쉬운 UI 개발을 가능하게 합니다. 이 글에서는 SwiftUI에서 데이터 상태를 관리하는 세 가지 주요 기법인 @ObservedObject, @State, @EnvironmentObject에 대해 설명하고, 이를 활용하여 애플리케이션을 더욱 유연하고 강력하게 만드는 방법을 다룹니다.

@State

@State는 SwiftUI에서 데이터의 상태를 관리하기 위한 속성 래퍼입니다. 이는 뷰의 내부 상태를 추적하면서 자동으로 뷰를 업데이트하는 데 사용됩니다. @State를 활용하면 뷰가 데이터 변경 사항을 감지해 자동으로 업데이트됩니다.

예를 들어, 간단한 카운터 애플리케이션을 생각해 봅시다:

swift
import SwiftUI

struct CounterView: View {
    @State private var count: Int = 0
    
    var body: some View {
        VStack {
            Text("Count: \(count)")
            Button(action: {
                count += 1
            }) {
                Text("Increment")
            }
        }
    }
}

위의 코드는 @State를 사용하여 count 변수를 선언하고, 버튼 클릭 시 이 변수를 증가시킵니다. @State 덕분에 count 값이 변경되면 해당 뷰(텍스트와 버튼)가 자동으로 업데이트됩니다.

@ObservedObject

@ObservedObject는 SwiftUI에서 뷰 외부에서 데이터를 관리하는 데 사용됩니다. 이는 보통 다양한 뷰에서 공유될 수 있는 모델 객체를 사용하여 데이터를 관리하려는 경우에 유용합니다.

ObservableObject 프로토콜을 준수하는 클래스와 함께 사용됩니다. 다음은 이를 활용한 예시입니다:

swift
import SwiftUI
import Combine

class CounterModel: ObservableObject {
    @Published var count: Int = 0
}

struct CounterView: View {
    @ObservedObject var counter = CounterModel()
    
    var body: some View {
        VStack {
            Text("Count: \(counter.count)")
            Button(action: {
                counter.count += 1
            }) {
                Text("Increment")
            }
        }
    }
}

이 예제에서는 CounterModel 클래스가 ObservableObject 프로토콜을 준수하고, count 변수를 @Published 속성으로 선언했습니다. CounterView@ObservedObject를 사용하여 이 모델을 관찰합니다. counter.count 값이 변경되면 뷰도 자동으로 갱신됩니다.

@EnvironmentObject

@EnvironmentObject는 SwiftUI의 뷰 계층 구조 전반에 걸쳐 데이터를 쉽게 공유하는 방법입니다. 이는 주로 뷰 계층 구조의 상위에서 하위로 데이터를 전달하는 데 사용됩니다.

다음 예제는 @EnvironmentObject를 사용하는 방법을 보여줍니다:

swift
import SwiftUI
import Combine

class AppModel: ObservableObject {
    @Published var isLoggedIn: Bool = false
}

struct ContentView: View {
    @EnvironmentObject var appModel: AppModel
    
    var body: some View {
        VStack {
            if appModel.isLoggedIn {
                Text("Welcome back!")
            } else {
                Button(action: {
                    appModel.isLoggedIn = true
                }) {
                    Text("Log in")
                }
            }
        }
    }
}

@main
struct MyApp: App {
    let appModel = AppModel()
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(appModel)
        }
    }
}

이 예제에서 AppModel@Published 속성을 사용하여 isLoggedIn 상태를 관리합니다. ContentView@EnvironmentObject를 통해 이 모델을 받아와 사용하며, MyAppenvironmentObject 수정자를 사용하여 AppModel을 전달합니다. 따라서 전체 뷰 계층 구조에서 AppModel에 접근할 수 있게 됩니다.

결론

SwiftUI에서의 데이터 관리와 상태 유지 방법은 애플리케이션의 성능과 유지보수성에 큰 영향을 미칩니다. @State, @ObservedObject, @EnvironmentObject는 각각 뷰의 내부 상태, 모델 객체의 상태, 그리고 뷰 계층 구조 전반에 걸친 상태 관리를 가능하게 합니다. 이 세 가지 기술을 적절히 활용하면 더욱 유연하고 확장 가능한 애플리케이션을 개발할 수 있습니다.