-
[RxSwift] - MVVM패턴과 RxSwift 사용iOS/RxSwift 2025. 4. 3. 13:17728x90반응형
팀 프로젝트 중 RxSwift를 적용한 반응형 프로그래밍에 관심이 생겼다.
기존에는 SwiftUI+Combine을 활용한 프로젝트를 해왔었는데 SwiftUI는 특성 상 바인딩을 직접 구현할 필요가 없었기 때문에 UIkit을 반응형 코드로 작성한다는 것에 궁금증이 생겼다.
MVVM 패턴은 익숙하다.
하지만 내가 모르는 기술(RxSwfit)과 새로운 프레임워크(내 기준에선 UIkit)를 사용해 프로젝트에 적용시켜보고 싶었다.
가장 처음으로 팀원 분의 도움으로 Json데이터를 fetch하는 메서드를 ViewModel에서 불러와 Model에 적용시켜, View와 바인딩 하는 로직을 RxSwift로 구현해봤다.
하나씩 톺아보자
ViewModel
import Foundation import RxSwift import RxCocoa final class BookViewModel { //MARK: 프로퍼티 선언 //disposeBag - 메모리 누수 방지 private let disposeBag = DisposeBag() //속성 배열 public var attributes = [Attributes]() // 데이터 변경을 감지하는 Subject var attributesSubject = PublishSubject<[Attributes]>() // 데이터 로드를 트리거하는 Subject var fetchSubject = PublishSubject<Void>() init() { cofigureBindings() } // MARK: - 바인딩 설정 private func cofigureBindings() { fetchSubject .subscribe(onNext: { [weak self] _ in self?.fetchAttributes() }) .disposed(by: disposeBag) } // MARK: - JSON 데이터 로드 private func fetchAttributes() { Task { do { let attributes = try await JsonManager.loadJson().get() self.attributes = attributes attributesSubject.onNext(attributes) } catch let error { attributesSubject.onError(error) } } } }fetchAttributes
해당 메서드는 필요 JSON 데이터 DTO로 디코딩해서 결과값&에러를 반환는 메서드이다.
해당 데이터를 불러오는 게 성공할 경우 Model에 저장하고 subject에 받아온 데이터를 emit한다.
실패 시, error를 emit한다.
cofigureBindings
헤당 메서드는 subject를 구독해 fetchAttributes를 실행하는 메서드이다.
viewmodel이 초기화 될 때, 해당 메서드를 실행시켜 바로 데이터를 Model에 저장하도록 한다.
즉, fetchSubject에 이벤트가 들어오면 JSON 데이터를 불러오는 트리거 역할을 한다.
VC에서 데이터가 변경되면 onNext로 emit을 할때 반응할 수 있는 스트림을 구현했다.
ViewController
private func bindViewModel() { vm.fetchSubject .onNext(()) vm.attributesSubject .observe(on: MainScheduler.instance) .subscribe(onNext: { [weak self] attributes in self?.configureBookView(attributes) self?.configureCollectionViewDelegate() self?.configureExpandButton() self?.configureSummaryStackView() },onError: { [weak self] error in guard let dataError = error as? DataError else { return } self?.showError(dataError) }) .disposed(by: disposeBag) }bindViewModel
VC에서는 해당 메서드를 viewDidLoad 시 호출한다.
ViewModel과 바인딩을 하는 메서드며, 위에서 설명한 것 처럼 fetchSubject의 이벤트를 방출한다.
Void로 선언했음으로 .onNext()에는 빈()값을 emit한다. 그렇게 되면 기존의 subject는 이에 반응하여 fetchInfo를 실행시킨다.
fetchAttributes에서 데이터를 불러오면 성패 여부에 따라 onNext 혹은 onError를 방출한다.
그러면 VC에서 구독을 하고 subject의 값으로 원하는 이벤트 핸들링을 추가해준다. 이때 이벤트는 MainScheduler에서 동작하기 때문에 순차적으로 실행된다.
코드 분석을 하긴 했는데, 온전히 내가 고민해본 코드가 아니라 조금 더 사용해보면서 연구가 필요할 듯 하다.
참고
[RxSwift] Rx+MVVM으로 로그인 화면을 만들어보자.
Rx+MVVM 예제를 살펴보면 주로 검색에 대한 테이블 뷰 화면, 또는 로그인 화면이 많은 것을 알 수 있는데, 실시간으로 반응해서 대응하는 화면이 Rx의 가장 큰 장점(반응형)을 돋보이게 할 수 있어
so-kyte.tistory.com
[RxSwift] 핵심 개념
1. Observable 1) 용어 - Observable : 관측(subscribe)되는 대상 - Observer (=subscriber) : Observable을 구독(subscribe)하는 주체 - emit : Observable이 이벤트를 방출하는 것 2) Observable에 이벤트 생성 - .just(value) - .of(value1
ios-development.tistory.com
'iOS > RxSwift' 카테고리의 다른 글
[RxSwift] - 단방향 Vs 양방향 (0) 2025.04.24