- RxSwift를 공부하며 pilgwon님이 번역하신 예제를 따라해 보고 제가 알아보기 쉽도록 정리해둔 글입니다.
ㅁ 예제 1
- City Searcher 만들기
- 도시 이름을 입력하면 동적으로 도시 목록을 보여줌.
ㅁ Code
ㅇ UI
@IBOutlet weak var tableView: UITableView!
@IBOutlet weak var searchBar: UISearchBar!
let allCities = ["NewYork", "London", "Paris", "Osaka", "Osagu", "Seoul"]
var shownCities = [String]()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return shownCities.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cityPrototypeCell", for: indexPath)
cell.textLabel?.text = shownCities[indexPath.row]
return cell
}
ㅇ Observable
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
tableView.dataSource = self
searchBar
.rx.text
.orEmpty
.subscribe(onNext: { [unowned self] query in
print("query: \(query)")
self.shownCities = self.allCities.filter({ $0.hasPrefix(query) })
self.tableView.reloadData()
})
.disposed(by: disposeBag)
}
- input:
- output:
- query: P
- query: Pa
- query: Par
- query: Pari
- query: Paris
- 위 코드대로 실행시 발생할 수 있는 문제
- issue #1: API 요청이 과도하게 발생할 수 있음
- solve: 타이핑 후 delay 추가 -> 검색 키워드가 변했는지 체크 -> 변한 경우에만 subscribe
- issue #2: 빈 값이 들어올 수 있음
- solve: filter로 빈 값이 아닌 경우만 subscribe
ㅇ Issue solved
searchBar
.rx.text
.orEmpty
.debounce(0.5, scheduler: MainScheduler.instance)
.distinctUntilChanged()
.filter({ !$0.isEmpty })
.subscribe(onNext: { [unowned self] query in
self.shownCities = self.allCities.filter({ $0.hasPrefix(query) })
self.tableView.reloadData()
})
.disposed(by: disposeBag)
- 이전에는 P, Pa, Par, Pari, Paris 총 5번 API를 콜했다면, subscribe 전 딜레이를 줌으로써
Paris
1번만 콜하는 방식으로 변경됐다.
- 예전에 처음 이 예제를 접했을 때는 무슨 뜻인지도 모르고 따라 치기 바빴는데,
Vue
를 접하면서 함수형 프로그래밍을 조금 맛보고, RxJS 퀵스타트 책을 보면서 기존에 있었던 어떤 문제를 해결하고자 Rx가 태동했는지 그 백그라운드를 자세하게 알고 난 후 보니 훨씬 이해가 잘 된다. (책 정말 강추합니다. 😂)
- Rx의 기능을 하나 하나 공부하기 전에 맛보기 예제를 통해 위와 같은 방식 혹은 상황에서 Rx를 이용할 수 있고, 기존 대비 코드가 매우 깔끔 + 간단해진다는 걸 알게 됐다.
- 벨로그에서 작성하는 마크다운의 코드블럭은 swift는 지원하지 않는건지 swift로 작성할 경우 코드블럭 내 컬러가 변하지 않는다. T.T 우선은 JS로 바꿔서 적어놓긴 했는데 눈에 잘 안들어와서 아쉬움.. 😭
ㅁ Link