본문 바로가기
프로그램 개발해서 돈벌기/iOS

[Swift] SwiftUI에서 두 개 뷰에서 @Published, ObservableObject, @StateObjec, @EnvironmentObject를 이용한 데이터 Combine 사용하기

by ubmuhan 2023. 11. 23.
반응형

Combine을 사용하는 가장 쉬운 방법 중 하나로, ObservableObject 프로토콜 클래스에서 사용될 때 자동으로 데이터 변경을 추적해 업데이트를 처리합니다.

 

[동작 요약]

  1. ObservableObject 클래스 내에서 @Published 속성 래퍼를 사용합니다.
  2. @Published 속성은 변경되는 사항을 등록한 모든 View에 알립니다.
  3. View는 @StateObject 프로퍼티 래퍼를 사용해 이 ObservableObject와 연결합니다.

 

한 개 뷰에서 Combine 예제

import SwiftUI

// ObservableObject 프로토콜을 채택하는 데이터 모델 클래스
class MyDataModel: ObservableObject {
    // @Published 속성을 사용하여 데이터 변경을 알림
    @Published var count: Int = 0
}

struct ContentView: View {
    // @StateObject를 사용하여 데이터 모델 인스턴스 생성
    @StateObject var myDataModel = MyDataModel()
    
    var body: some View {
        VStack {
            Text("Count: \(myDataModel.count)")
                .font(.largeTitle)
            
            Button(action: {
                // 버튼을 누를 때마다 count 값을 증가시킴
                myDataModel.count += 1
            }) {
                Text("Increase Count")
                    .font(.title)
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

SwiftUI에서 @Published, ObservableObject, @StateObject를 사용하는 방법을 보여줍니다. MyDataModel 클래스는 ObservableObject 프로토콜을 채택하여 데이터 변경을 알릴 수 있도록 구현되었습니다. count 속성에 @Published 속성이 적용되어 있어, 값이 변경될 때마다 SwiftUI에게 해당 변경을 알립니다.

 

ContentView@StateObject를 사용하여 myDataModel 인스턴스를 생성합니다. 이렇게 하면 SwiftUI가 myDataModel의 변경을 추적하고 뷰를 자동으로 업데이트할 수 있게 됩니다. 버튼을 누를 때마다 myDataModel.count 값을 증가시키고, 뷰에 표시되는 텍스트가 자동으로 업데이트됩니다.

 

예제를 실행해 보면 그림 1과 같이 버튼을 누를 때마다 텍스트가 업데이트되는 것을 확인할 수 있습니다. 이처럼 @Published, ObservableObject, @StateObject를 사용하면 데이터 모델의 변경을 SwiftUI에 알릴 수 있고, 뷰를 업데이트할 수 있습니다.

 

그림 1. 한개 뷰에서 Combine 예제 실행 화면

 

 

두 개 뷰에서 Combine 예제

import SwiftUI

// ObservableObject 프로토콜을 채택하는 데이터 모델 클래스
class MyDataModel: ObservableObject {
    // @Published 속성을 사용하여 데이터 변경을 알림
    @Published var count: Int = 0
}

struct ContentView: View {
    // @StateObject를 사용하여 데이터 모델 인스턴스 생성
    @StateObject var myDataModel = MyDataModel()
    
    var body: some View {
        VStack {
            Text("Count: \(myDataModel.count)")
                .font(.largeTitle)
            
            Button(action: {
                // 버튼을 누를 때마다 count 값을 증가시킴
                myDataModel.count += 1
            }) {
                Text("Increase Count")
                    .font(.title)
                    .padding()
                    .background(Color.blue)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
            
            // ChildView에서도 myDataModel을 사용하도록 환경 객체로 설정
            ChildView()
                .environmentObject(myDataModel)
        }
    }
}

struct ChildView: View {
    // ContentView에서 사용 중인 myDataModel 인스턴스를 가져옴
    @EnvironmentObject var myDataModel: MyDataModel
    
    var body: some View {
        VStack {
            Text("Count: \(myDataModel.count)")
                .font(.largeTitle)
            
            Button(action: {
                // 버튼을 누를 때마다 count 값을 감소시킴
                myDataModel.count -= 1
            }) {
                Text("Decrease Count")
                    .font(.title)
                    .padding()
                    .background(Color.red)
                    .foregroundColor(.white)
                    .cornerRadius(10)
            }
        }
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

 

ChildViewContentView 안에 포함되어 있습니다. ChildView에서는 @EnvironmentObject를 사용하여 myDataModel 인스턴스를 가져옵니다. 이렇게 하면 ChildViewmyDataModel의 변경을 추적하고 자동으로 업데이트할 수 있습니다.

 

ContentView에서는 ChildView를 추가로 표시하고, 버튼을 누를 때마다 myDataModel.count 값을 증가시키거나 감소시킵니다. 이렇게 하면 ContentViewChildView에서 모두 같은 데이터 모델을 사용하며, 데이터 변경에 따라 두 개의 뷰가 동기화됩니다.

 

예제를 실행해 보면 그림 2. 와 같이 ContentViewChildView에 표시된 텍스트와 버튼이 동시에 업데이트되는 것을 확인할 수 있습니다. 이처럼 @EnvironmentObject를 사용하면 여러 개의 뷰에서 동일한 데이터 모델을 공유할 수 있습니다.

 

그림 2. 두개 뷰에서 Combine 예제 실행 화면

반응형

댓글