[RxSwift] 15. RxSwift + URLSession, MVVM 리팩토링 2

miori·2022년 3월 2일
0

RxSwiftBasic

목록 보기
28/29

꾸준히 가야돼! "Rx를 기깔나게 쓰는 신입개발자 도전" 🚀


결과물

filter output

이번엔, 위의 결과물처럼 네비게이션 상단 우측 바버튼 (list.bullet)을 눌렀을때 OLD/NEW 를 필터링 해서 보여주는 기능을 Rx + MVVM 으로 구현해보았다.

설계 요구사항

  1. 네비게이션 상단에 오른쪽에 버튼을 추가한다.
  2. 오른쪽 버튼의 모양은 list.bullet 의 시스템 이미지를 활용한다.
  3. 오른쪽 버튼은 계속 누를 수 있으며 누른 횟수에 따라 보여지는 셀 데이터가 달라진다.

버튼의 역할

  • 버튼을 누르면 rankOldAndNew 항목이 NEW 인값만 보여준다.
  • 한번더 누를시, 리셋이 되어 다시 모든 데이터를 보여준다.

코드

- Model

우선, 버튼의 가장 큰 역할인 필터 기능을 해주는 함수를 모델에 구현하였다.
모델에 따로 코드를 빼서 구현한 이유는 데이터모델을 가지고 filter를 하는 기능이기 때문에 ViewModel 보다는 Model이 적합하다고 생각했다.

함수는 버튼이 몇번 눌렸는지에 대한 Int값과 데이터객체인 [BoxOfficeList]를 파라미터로 받고, [BoxOfficeList]를 return 한다.

struct BoxOfficeModel {
    func goFilter(type : Int, data : [BoxOfficeList]) -> [BoxOfficeList] {
        if type == 0 {
            return data
        } else {
            return data.filter {
                $0.rankOldAndNew == "NEW"
            }
        }
    }
}

- ViewModel

ViewModel에 다음과 같은 코드를 추가하였다.

let outputData = filterBtnTapped
    .map { _ -> Int in
        cnt += 1
        if cnt % 2 == 1 {
            return 1
        } else {
            return 0
        }
    }
    .startWith(0)


Observable
    .combineLatest(outputData, cellData, resultSelector: boxOfficeModel.goFilter)
    .bind(to: apiData)
    .disposed(by: disposeBag)
  • filterBtn은 PublishRelay<Void>() 로 선언하였다.
    - Relay를 사용한 이유는 error나 completed없이 Dispose되기 전까지 계속 작동하기 때문이다.
  • filterBtn을 누를때 마다 횟수가 늘고, 시작값은 0으로 하였다. (startWith)
  • 누른 횟수가 홀수 일때는 1을 짝수일때는 0을 return 하게 했다.
  • outputData와 cellData를 두개의 소스를 받아 resultSelector 처럼 구현하게끔 하였다.
  • cellData는 지난번에 구현한 셀에 뿌려질 Observable<[BoxOfficeList]> 이다.
  • resultSelector는 model에서 구현한 goFilter이기 때문에 두 옵저버블이 goFilter를 통해 Observable<[BoxOfficeList]>를 return 한다.

- view

view의 bind함수 내에서, 다음과 같이 구현할 수 있다.

filterBtn.rx.tap
    .bind(to: viewModel.filterBtnTapped)
    .disposed(by: disposeBag)

버튼 tap과 viewModel.filterBtnTapped를 바인딩 하였다.


cocoatouch 를 사용한다면, tableView.reloadData() 를 활용한다면 쉽게 구현했을 것 같다.
하지만 rx로 구현했을때의 느껴지는 장점도 있다.

  • 로직이 확실히 나뉘어진다.
    - cocoatouch의 경우 나누기가 너무 애매했었는데 rx를 view와 viewModel의 바인딩이 가능해서 그런지 코드를 잘 쪼갤수 있다.

  • 버튼 함수 구현을 하지 않아도 된다.
    - addTarget을 써서 Objective-C 함수를 구현하지 않아도 되는 부분이 너무 깔끔하게 느껴졌다.

여태껏 coocatouch를 사용해 개발을 해왔기 때문에 rx가 손에 익지 않고 어려움이 있는건 확실하다.
하지만 도전하면 안될건 없다고 생각한다.
구현하고 나면, 코드가 너무 직관적이라서 rx의 매력에 조금씩 빠져드는 것 같다.
무엇보다 rx로 구현하고자 하는 기능이 구현이 되면... 진짜 엄청 뿌듯하다.😆


코드 깃헙 링크

profile
iS를 공부하는 miori 입니다.

0개의 댓글

관련 채용 정보