Tunko Development Diary

[SwiftUI] Observable 객체 정리 본문

Development/iOS 개발

[SwiftUI] Observable 객체 정리

Tunko 2021. 2. 22. 17:47

예제 코드

import Foundation
import Combine

class DemoData : ObservableObject {

    @Published var userCount : Int = 0

    // 초기화
    init() {
        initData()
    }

    func initData()
    {
        userCount = 0
    } 
}
import SwiftUI

struct DemoContentView: View {

    @ObservedObject var demoData: DemoData

    var body: some View {
        VStack {
            Demo1View(demoData: demoData)
            Button(action: {
                demoData.userCount += 1
            }) {
                Image(systemName: "car.fill")
                    .resizable()
                    .aspectRatio(contentMode: .fit)
                    .frame(width: 130, height: 100, alignment: .center)
            }
        }
    }
}


struct Demo1View : View {
    @ObservedObject var demoData: DemoData
    var body: some View {
        VStack {
            Text("demoData userCount * 1 : \(demoData.userCount * 1)")
            Demo2View(demoData: demoData)
        }
    }
}
struct Demo2View : View {
    @ObservedObject var demoData: DemoData
    var body: some View {
        Text("demoData userCount * 2 : \(demoData.userCount * 2)")
        Demo3View(demoData: demoData)
    }
}
struct Demo3View : View {
    @ObservedObject var demoData: DemoData
    var body: some View {
        Text("demoData userCount * 3 : \(demoData.userCount * 3)")
    }
}

struct DemoContentView_Previews: PreviewProvider {
    static var previews: some View {
        DemoContentView(demoData: DemoData())
    }
}

요약

여기서 ObservableObject 프로토콜로 정의된 클래스 DemoData가 있다.
DemoData는 뷰에서 @ObservedObject 를 통해 선언해 사용할 수 있다.
DemoData 내부에 @Published로 선언된 변수 userCount 를 다른 뷰에서 사용하게 되면 해당 변수를 사용하는 모든 뷰가 최신 변경된 값을 반영하기위해 다시 랜더링 된다.

설명

뷰 내부에서 DemoData 로 정의된 객체의 값이 변경되면 해당 데이터를 사용하고 있는 뷰가 다시 변경된 값을 반영하여 다시 렌더링 된다.

상태 프로퍼티는 뷰의 상태를 저장하는 방법을 제공하여 해당 뷰에만 사용할 수 있다. 즉, 하위 뷰가 아니거나 상태 바인딩이 구현되어 있지 않은 다른 뷰는 접근할 수 없다. 상태 프로퍼티는 일시적인 것이어서 부모 뷰가 사라지면 그 상태도 사라진다. 반면, observable 객체는 여러 다른 뷰들이 외부에서 접근 할 수 있는 영구적인 데이터를 표현하기 위해 사용된다.

Observable 객체는 ObservableObject 프로토콜을 따르는 클래스나 구조체 형태를 취한다. Observable 객체는 데이터의 특성과 출처에 따라 애플리케이션마다 다르겠지만, 일반적으로는 시간에 따라 변경되는 하나 이상의 데이터 값을 모으고 관리하는 역할을 담당한다.
또한, Observable 객체는 타이머나 알림(notification) 과 같은 이벤트를 처리하기 위해 사용될 수도 있다.

Observable 객체는 게시된 프로퍼티(published property) 로서 데이터 값을 제시 (publish)한다. 그런다음 observer 객체는 게시자를 구독(subscribe) 하여 게시된 프로퍼티가 변경될 떄마다 업데이트를 받는다.

앞에서 설명한 상태 프로퍼티처럼, 게시된 프로퍼티와의 바인딩을 통해 Observable 객체에 저장된 데이터가 변경된을 반영하기 위하여 SwiftUI 뷰는 자동으로 업데이트 될 것이다.

Combine 프로임 워크에 포함되어 있는 Observable 객체는 게시자(publisher)와 구독자(subscriber) 간의 관계를 쉽게 구축할 수 있ㄷ록 iOS13에 도입되었다.

Combine 프레임워크는 여러 게시자를 하나의 스트림으로 병합하는 것부터 게시된 데이터를 구독자 요구에 맞게 변형하는것까지 다양한 작업을 수행하는 커스텀 게시자 구축 플랫폼을 제공한다. 또한, 최초 게시자와 최종 구독자 간에 복잡한 수준의 연쇄 데이터처리 작업도 구현할 수 있다. 하지만, 일반적으로는 내장된 게시자 타입들 중 하나면 충분할 것이다. 실제로 Observable 객체의 게시된 프로퍼티를 구현하는 가장 쉬운 방법은 프로퍼티를 선언할 떄 @Published프로퍼티 래퍼를 사용하는 것이다. 이 래퍼는 래퍼 프로퍼티 값이 변경 될 떄 마다 모든 구독자에게 업데이트를 알리게 된다.

다음의 구조체 선언은 두 개의 게시된 프로퍼티를 가진 간단한 observable객체 선언을 보여준다.

반응형
Comments