[RxSwift] 10-1. RxCocoa in TableView

miori·2022년 2월 23일
0

RxSwiftBasic

목록 보기
21/29

RxSwift를 21일간 공부하는 루틴
"Rx를 기깔나게 쓰는 신입개발자 도전" 시작 🚀


RxCocoa를 활용하여, TableView에 데이터를 표시해보면서 지금까지 공부해본것을 리뷰해보려고 한다.

구현

- 구현 목표

이번 구현도 나의 취미은 크로스핏을 예제로 들었다.
조금더 이해를 돕기위해 살짝 설명을 하자면,
크로스핏에선 운동을 WOD(Workout Of the Day)라고 칭한다.

  • 운동이름 : WOD의 이름을 나타낸다.
  • 카테고리 : 유명한 와드들은 Girl's Name이나 Hero 라는 카테고리를 가진다.
  • 상세동작 : 와드에서 수행해야할 동작들이다.
  • 무게레벨링 : rx 는 와드에서 제공하는 최고 레벨의 무게이다.

1. 운동 이름, 카테고리, 상세 동작, 무게 레벨링 을 포함하는 데이터를 테이블뷰에 띄운다.
목표1
2. 각 셀을 탭 했을때, alert으로 운동이름과, 상세동작을 띄어준다.
목표2

- 사용 라이브러리

🛠 라이브러리
- rxswift
- rxcocoa
- snapkit

- 구현

1. 셀에 띄우기

만약 rx를 사용하지 않는다면 delegate 를 사용해서 구현을 했었을 것이다.
하지만 rx를 사용한다면 delegate없이 데이터 Observable과 table View 를 바인딩하여 cell에 뿌려줄 수 있다.

이런 기능을 가능하게 해주는 메서드 중 셀을 파라미터로 전달하는 메서드를 사용해보았다.

    public func items<Sequence: Swift.Sequence, Cell: UITableViewCell, Source: ObservableType>

이 메서드와 달리, 셀을 파라미터로 전달하지 않는 메서드도 있다.
이 두부분은 추후에 비교해보겠다.

        // 클로저로 전달되는 파라미터 row, element, cell
        // 파라미터로 전달되는 cell은 RXTableViewCell.self로 타입캐스팅 되서 전달됨
        allObservable.bind(to: tableView.rx.items(cellIdentifier: RXTableViewCell.registerID, cellType: RXTableViewCell.self)) { [weak self] row, element, cell in
            // 셀 구성
            cell.setData(element)
        }
        .disposed(by: disposeBag)

RXTableViewCell 은 커스텀으로 구현한 테이블뷰 셀이다.

  • 클로저로 전달되는 파라미터 : row, element, cell

4개의 UILabel을 snapkit을 활용해 구현하였다.

cell.setData(element) 는 label의 text에 각각의 값을 넣어주는 역할을 한다.

    func setData(_ dataEntity : CrossfitMovements) {
        categoryLabel.text = dataEntity.category.rawValue
        nameLabel.text = dataEntity.name
        movementsLabel.text = dataEntity.movements
        levelLabel.text = dataEntity.level
    }

본론으로 돌아와, rx로 구현한 코드를 보면 delegate로 구현했을때보다 훨씬 간단하고 직관적이다.
왜냐하면 delegate로 구현한다 생각하면, numberOfRowsInSectioncellForRowAt 를 활용해 return 할 row의 수와 UITableViewCell을 지정해줘야하기 때문이다.
하지만 rx로 구현한다면, 굳이 row의 수를 return하는 함수를 쓸 이유가 없다.

2. 셀 select

delegate를 사용한다면, didSelectRowAt 를 사용할 수 있다.
이러한 역할을 해주는 메서드는 rx에도 존재한다.
itemSelected

definition 에서 보이듯이 결국은 delegate를 감쌌다고 볼 수 있다.

itemSelected의 경우 셀 선택시 next 이벤트를 전달하고 indexPath가 저장이 된다.

또한 바로 model의 데이터 값을 주는 메서드인 modelSelected 가 있다. 이땐 model의 type도 같이 넘겨줘야한다.

다시 돌아와, itemSelected 를 써서, 탭한 셀의 gray backgroundcolor가 유지되는 것을 없애보았다.

tableView.rx.itemSelected
    .bind { [weak self] indexPath in
        self?.tableView.deselectRow(at: indexPath, animated: false)
    }
    .disposed(by: disposeBag)
  • delegate와 비교해보면, 훨씬 직관적이라고 생각한다.
    이유는 코드 그대로 읽으면 "item이 select 되었을때, deselectRow를 할거임!" 이렇게 바로 해석이 가능하기 때문이다.

delegate와 비교했을때, rx의 장점이 있는 것은 분명하지만, 단점도 몇가지 느꼈다.
rx에서 제공해주는 메서드가 없는 경우도 있다.
예를 들어 section을 나누고 싶지만, RxDataSources 라이브러리를 사용해야 구현할 수 있다.

전체코드는 링크를 걸어놓았다.


두번째 구현인 alert 띄우는 부분은 다음 글에서 정리해보도록 하겠다.


회고

rx 를 활용했을때, 시너지가 나는 부분과 굳이 사용하지 않아도 되는 부분은 언제든지 존재할 것 같다.
이런 부분을 잘 캐치해내는 개발자가 되어야겠다.
물론 개인적의 시각의 차이가 있겠지만, 내가 왜 여기서 rx를 썼고 혹은 왜 여긴 rx를 쓰지 않았는지에 대한 로직을 갖고 개발을 해야겠다.
그리고 로직을 잘 정리하고 팀원들에게 조리있게 말할수 있는 개발자가 되어야겠다.
그렇지만... 조리있게 글쓰고 말하는 거.. 너무 어렵다.☹️

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

0개의 댓글

관련 채용 정보