RxSwift Beginners Episode 1 - Transform a classic TableView App into a Reactive one
viewModel
.rows
.bind(to: resultsTableView.rx.items(cellIdentifier: "WikipediaSearchCell", cellType: WikipediaSearchCell.self)) { (_, viewModel, cell) in
cell.title = viewModel.title
cell.url = viewModel.url
}
.disposed(by: disposeBag)
bind
및 disposed
가 해당 테이블 뷰에 적용되고 있는데, Rx를 사용하지 않으면 세 줄로는 표현이 불가능함Composible
: 구성 및 조합이 가능Resuable
: 코드 재활용Declarative
: 선언적 → 정의는 불변, 데이터만 변하기 때문Understandable and concise
: 추상화 레벨을 높이고 일시적인 상태를 없앰Stable
: 전적으로 유닛 단위Less stateful
: 단방향 데이터 플로우로 어플리케이션을 모델링하기 때문Without leaks
: 리소스 관리가 간단RxSwift의 최대 장점은 iOS9부터 지원이 가능하다는 점이라 생각한다. iOS13부터 스위프트 공식 지원 프레임워크로
Combine
이 들어왔고, iOS15부터는async/await
가 가능하기 때문이다.
Combine
을 보다 쉽게, async/await
를 보다 간편하게 접근할 수 있으리라 믿는다.Observable
을 구독, 값의 변화를 알림 받는 역할Observable
, rx
, disposed
를 통한 감지 / 감지에 대한 반응 / 메모리 관리하기 private func setTableViewRx() {
tableViewRxItems
.bind(to: tableView
.rx
.items(cellIdentifier: "tableViewCell")) {
(tv, tableViewItem, cell) in
cell.textLabel?.text = tableViewItem
}
.disposed(by: disposeBag)
}
import UIKit
import RxSwift
import RxCocoa
class ViewController: UIViewController {
let tableViewRxItems = Observable.just(["Item 1", "Item 2", "Item 3", "Item 4"])
@IBOutlet weak var tableView: UITableView!
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
setTableViewRx()
}
private func setTableViewRx() {
tableViewRxItems
.bind(to: tableView
.rx
.items(cellIdentifier: "tableViewCell")) {
(tv, tableViewItem, cell) in
cell.textLabel?.text = tableViewItem
}
.disposed(by: disposeBag)
}
}
Combine
프레임워크와 같은 동작 → 관찰을 받는 퍼블리셔Observable
, 퍼블리셔에 대한 구독 rx
, 구독을 취소하거나 해당 값을 저장하는 공간 cancellables
-DisposeBag
tv, tableViewItem, cell
은 각각 해당 테이블 뷰, 해당 테이블 뷰에 매칭되는 데이터, 데이터에 씌울 셀을 의미items
를 통해 몇 번째 셀에 몇 번째 인덱스 값이 들어갈지 알 수 있는 까닭은 tableViewRxItems
에서 Observable.just()
를 통해 등록했기 때문public static func just(_ element: Element) -> Observable<Element> {
Just(element: element)
}
// Returns an observable sequence that contains a single element.
Just
. Combine
의 Just
와 매우 유사import UIKit
class ViewController: UIViewController {
let tableViewItems = ["Item 1", "Item 2", "Item 3", "Item 4"]
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
setTableView()
}
private func setTableView() {
tableView.delegate = self
tableView.dataSource = self
}
}
extension ViewController: UITableViewDelegate, UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return tableViewItems.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "tableViewCell")
cell.textLabel?.text = tableViewItems[indexPath.row]
return cell
}
}
RxSwift에 등장하는
sink
개념 등 이전Combine
프레임워크를 익힐 때 마주쳤던 개념이 매우 많다! 다시 한 번 짚고 가면서 비동기 데이터를 처리하는 방법론 자체에 익숙해지자.