SwiftUI) Observation 프레임워크란?

애플은 WWDC 2023에서 새로운 프레임워크인 Observation을 발표했습니다. 이 글에서는 Observation이 무엇인지, 어떻게 사용하는지, 그리고 기존 코드와 비교하여 어떤 장점이 있는지 알아보겠습니다.

Observation이란?

Observation은 애플이 WWDC 2023에서 소개한 새로운 프레임워크로, 데이터가 변화될 때 프레젠테이션을 업데이트할 수 있도록 하는 반응형 앱을 만들 수 있게 해줍니다. 공식 문서에 따르면, Observation 프레임워크는 다음과 같은 기능을 제공합니다:

  • 타입을 관찰 가능하도록 표시합니다.
  • 관찰 가능한 타입 인스턴스 내에서의 변경 사항을 추적합니다.
  • 앱의 사용자 인터페이스와 같이, 다른 곳에서 이러한 변경 사항을 관찰하고 활용할 수 있습니다.

이 기능들은 기존 SwiftUI에서 사용하는 ObservableObject와 매우 유사합니다. 이제 실제 사용법을 살펴보고, 어떻게 다른지 비교해보겠습니다.

Observable 사용해보기

먼저, 간단한 ViewModel을 만들어보겠습니다.

@Observable class User {
    var name: String = "Kim"
    var age: Int = 26
    var followers = 100
    var email = "apple@apple.com"
}
struct ContentView: View {
    var user = User()
    
    var body: some View {
        VStack(alignment: .leading) {
            Text("name :  \(user.name)")
                .font(.title)
            Text("age: \(String(user.age))")
            Text("email: \(user.email)")
            Text("followers: \(user.followers)")
            Button(action: {
                user.followers += 1
            }, label: {
                Text("Add Follower")
            })
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}
class User2: ObservableObject {
    @Published var name: String = "Kim"
    @Published var age: Int = 26
    @Published var followers = 100
    @Published var email = "apple@apple.com"
}

위의 코드에서 ObservableObject로 구현한 부분은 아래와 같습니다.

이처럼 ObservableObject로 할 수 있던 기능을 @Observable을 통해 좀 더 간결하게 구현할 수 있습니다. 컴파일 타임에 observation 코드가 자동으로 생성되기 때문입니다. 하지만 여기까지 봤을 때는 새로운 Observable 매크로를 사용해야 하는 이유가 명확하지 않을 수 있습니다.

Observable의 장점

뷰 랜더링의 효율성

다음은 Observable 매크로와 ObservableObject를 사용한 예제입니다.

struct ContentView: View {
    var user = User()
    @StateObject var user2 = User2()
    
    var body: some View {
        VStack(alignment: .leading) {
            Text("name :  \(user.name)")
                .font(.title)
                .background(.random)
            Text("age: \(String(user.age))")
                .background(.random)
            Text("email: \(user.email)")
                .background(.random)
            Text("followers")
                .background(.random)
            Button(action: {
                user.followers += 1
            }, label: {
                Text("Add Follower")
            })
            .buttonStyle(.borderedProminent)
        }
        .padding()
        
        VStack(alignment: .leading) {
            Text("name :  \(user2.name)")
                .font(.title)
                .background(.random)
            Text("age: \(String(user2.age))")
                .background(.random)
            Text("email: \(user2.email)")
                .background(.random)
            Text("followers")
                .background(.random)
            Button(action: {
                user2.followers += 1
            }, label: {
                Text("Add Follower")
            })
            .buttonStyle(.borderedProminent)
        }
        .padding()
    }
}

위의 예제에서, 각각의 프로퍼티는 백그라운드를 랜덤으로 설정했습니다. 만약 다시 랜더링이 된다면 백그라운드 색상이 바뀔 것입니다. Add Follower 버튼은 followers 값을 +1 하지만 그 값은 UI에 사용되지 않습니다. 여기서 각각의 버튼을 누르면 어떻게 반응할까요?

Observable 매크로로 만든 윗 부분의 버튼을 누르면 배경 색이 바뀌지 않지만, ObservableObject로 만든 아랫 부분의 버튼을 누르면 배경 색이 계속 바뀌는 것을 알 수 있습니다.

이는 Observable 매크로가 변경된 값을 View에서 관찰하지 않기 때문에 뷰가 상태 변경에 대해 알림을 받지 않기 때문입니다. 따라서 Observable을 사용하면 불필요한 뷰의 랜더링을 방지하고 앱의 성능을 향상시킬 수 있습니다.

Leave a Comment