[RxSwift] UI의 data타입을 Driver<>로 하는 경우?

sun02·2022년 3월 21일
0

RxSwift

목록 보기
12/12

왜 Driver<> 일까?

먼저 RxCocoa가 가지는 Trait에는 driver와 signal이 있습니다.
두 가지 trait 모두 UI층에서 reactive programming을 위해 사용됩니다.

따라서 이와 같은 두 가지 특징을 공통적으로 가집니다.

  • 오류 반환하지 않음
  • 메인스레드에서의 실행을 보장

그렇기에 UI의 데이터를 뿌려주기 위해서는 driver 또는 signal를 사용하는게 좋습니다.

Driver와 Signal의 차이

: Driver와 Signal을 구독한 순간 replay는 다음과 같이 발생합니다.

  • Driver는 구독하는 순간 최신값(b)을 replay합니다.
  • Signal은 replay하지 않고 구독한 이후의 값(c)만을 방출합니다.

대부분 replay가 되지 않는 것이 문제가 되는 경우가 많기 때문에 Driver가 더 많이 사용되곤 합니다.

예를 들어, viewModel과 View의 바인딩과 첫번째 trigger의 타이밍이 다른 경우가 있습니다.
trigger가 바인딩 전에 발생한다면 첫번째 이벤트가 발생하지 않을 수 있습니다.
그러나 driver를 사용한다면 이러한 버그를 신경쓰지 않아도 됩니다. (최신 값을 replay하기 때문에)

결론

Driver는 최신값을 replay하기 때문에 바인딩과 trigger의 타이밍 차이로 놓칠 수도 있는 first trigger를 놓칠 우려가 없습니다.
따라서 데이터를 놓치고 싶지 않을 때 Signal보다 Driver를 사용하는 것이 좋습니다.

참고자료- [Medium] Signal and Relay in RxCocoa 4

TableView에 driver로 데이터 제공하는 예시

먼저 구조는 다음과 같습니다.

LocalInformationViewController가 detailList라는 UITableView()를 가집니다.

- ViewModel - > View

LocalInformationViewModel -> LocalInformationViewController
detailList의 데이터를 전달해주어야하기 때문에

LocalInfromationViewModeldetailListCellData를 가집니다.
이 detailListCellData의 타입은 Driver<[DetailListCellData]> 입니다.

- LocationInformationViewModel.swift

let detailListCellData : Driver<[DetailListCellData]>
let documentData = PublishSubject<[KLDocument]>()

init(model: LocationInfromationModel = LocationInfromationModel()) {
	// 다른 코드 생략
    
    detailListCellData = documentData
            .map(model.documentsToCellData(_:))
            .asDriver(onErrorDriveWith: .empty())
}
  • LocationInformationModel의 documentsToCellData() 메서드가 documnetData를 KLDocumnet타입에서 DetailListCellData타입으로 변환합니다.
  • asDriver()를 이용하여 PublishSubject를 Driver로 변환합니다.

- LocationInformationViewController.swift

let detailList = UITableView()

func bind(_ viewModel: LocalInformationViewModel) {
	viewModel.detailListCellData
    .drive(detailList.rx.items) { tableView, row, data in
    	let cell = tableView.dequeueReusableCell(withIdentifier: "DetailListCell", for: IndexPath(row: row, section: 0)) as! DetailListCell 
    
    	cell.setData(data)
    	return cell
    }
    .disposed(by: disposebag)
}
  • driver는 drive 메소드를 사용해서 event를 처리합니다.
    • items는 rxcocoa가 UITableView에 대해 자체적으로 가지고 있는 메소드 입니다.

0개의 댓글