[SwiftUI] Combine을 이용한 실시간 데이터 구독 및 업데이트

2024. 9. 22. 01:43Computer/Apple Ecosystem Insights

SwiftUI와 Combine은 iOS 앱 개발에서 비동기 데이터 처리를 매우 간단하고 효율적으로 만들어줍니다. 특히, @Published와 Combine의 구독 기능을 활용하면 데이터가 실시간으로 업데이트될 때마다 뷰를 자동으로 새로고침할 수 있습니다. 이번 포스트에서는 ProfileViewModel 예제를 통해 SwiftUI에서 Combine을 활용하여 실시간으로 데이터를 업데이트하고, 이를 효율적으로 관리하는 방법을 소개하겠습니다.

코드 예시: ProfileViewModel

class ProfileViewModel: ObservableObject {
    @Published var currentUser: User?
    private var cancellables = Set<AnyCancellable>()

    init() {
        setupSubscribers()
    }

    private func setupSubscribers() {
        UserService.shared.$currentUser.sink { [weak self] user in
            self?.currentUser = user
        }.store(in: &cancellables)
    }
}

이 코드는 사용자의 프로필 데이터를 실시간으로 업데이트하여 SwiftUI 뷰에 반영하는 ProfileViewModel을 정의합니다. Combine을 활용한 데이터 구독과 @Published 프로퍼티를 사용하여 SwiftUI와의 상태 연동을 간편하게 설정할 수 있습니다.

코드 분석

1. class ProfileViewModel: ObservableObject

ProfileViewModelObservableObject 프로토콜을 채택하고 있습니다. 이를 통해 ViewModel이 SwiftUI 뷰에 데이터를 제공하고, 데이터가 변경될 때 뷰가 자동으로 업데이트될 수 있도록 만듭니다.

2. @Published var currentUser: User?

@Published 속성 래퍼는 currentUser가 업데이트될 때마다 SwiftUI가 해당 변경 사항을 감지하고 뷰를 다시 렌더링하게 합니다. 이는 데이터 흐름을 반응형으로 관리할 수 있도록 해주며, 사용자 정보가 변경될 때 뷰에 즉시 반영됩니다.

3. private var cancellables = Set<AnyCancellable>()

Combine을 통해 데이터를 구독할 때, 구독을 취소할 수 있는 객체인 AnyCancellable을 저장하는 컬렉션입니다. Swift에서 메모리 누수를 방지하고 구독을 필요에 따라 해제하기 위해 Cancellable을 관리하는 것이 중요합니다.

4. init()setupSubscribers()

init 메서드는 ProfileViewModel 객체가 생성될 때 호출되며, setupSubscribers() 메서드를 통해 Combine 구독 설정을 초기화합니다.

5. UserService.shared.$currentUser.sink { [weak self] user in ... }

이 부분은 Combine의 핵심입니다. UserService@Published로 선언된 currentUser를 구독(subscribe)하여 데이터가 변경될 때마다 클로저가 실행됩니다. [weak self]는 순환 참조를 방지하기 위해 사용되며, self를 약한 참조로 가져와 메모리 관리에 신경 씁니다.

6. self?.currentUser = user

데이터 스트림에서 전달된 user 객체를 뷰모델의 currentUser에 할당합니다. 이로 인해 SwiftUI 뷰는 변경된 데이터를 감지하고, 해당 뷰가 새롭게 렌더링됩니다.

7. print("DEBUG: User in view model from combine is \(user)")

디버깅을 위해 Combine을 통해 전달된 데이터를 출력하는 코드입니다. 이 코드는 실시간 데이터 흐름을 확인할 때 유용하게 사용할 수 있습니다.

8. .store(in: &cancellables)

구독을 완료한 후 cancellables에 저장하여 메모리 누수 방지 및 구독 관리가 가능하게 만듭니다. 이 메서드는 Combine 구독이 필요 없어질 때 메모리에서 자동으로 해제되도록 보장해 줍니다.


왜 이 코드가 필요한가?

  1. 실시간 데이터 반영: 앱 내에서 사용자 정보가 변경되었을 때, 이를 실시간으로 반영해야 할 때 매우 유용합니다. 예를 들어, 사용자가 로그인하거나 로그아웃할 때 해당 정보를 뷰모델에서 자동으로 업데이트할 수 있습니다.
  2. 메모리 관리: 구독이 끝났을 때 메모리를 효율적으로 관리하기 위해서는 구독을 해제할 수 있어야 합니다. Combine의 AnyCancellable을 사용하면 불필요한 구독을 해제할 수 있어 메모리 누수를 방지할 수 있습니다.
  3. 반응형 앱 설계: SwiftUI의 강점 중 하나는 데이터와 뷰 간의 반응형 흐름입니다. Combine을 사용하면 데이터가 변할 때마다 뷰가 자동으로 변경되므로, 사용자는 자연스럽고 실시간으로 업데이트되는 UI를 경험할 수 있습니다.

결론

Combine을 사용하면 데이터 흐름을 간단하게 구독하고, 실시간으로 상태가 변경될 때 뷰를 쉽게 업데이트할 수 있습니다. SwiftUI와 결합된 이러한 메커니즘은 현대 iOS 앱 개발에서 매우 강력한 도구가 될 수 있습니다. 특히, @Published와 Combine의 구독 패턴은 데이터 흐름을 효율적으로 관리하고, 메모리 관리까지 신경 쓰는 앱 개발에 필수적입니다.

반응형