꾸준히 가야돼! "Rx를 기깔나게 쓰는 신입개발자 도전" 🚀
우선, 피그마로 대략적으로 그려본 뷰이다. (물론 디자이너분이랑 비교가 안되지만, 혼자 작업할때 피그마로 대략적으로 만들 뷰를 그려보면 구조가 잡혀, 시간을 투자하여 피그마로 그려보는 편이다)
이 API를 postman으로 테스트 해본 결과, 이상한 점을 발견하였다.
"파이썬" 이라는 키워드로 검색을 하였을 때 startIndex 쿼리가 바뀔때마다 totalItems 수가 랜덤하게 계속 변했다.
이렇게 되면 추후에 무한 스크롤을 구현할때, 어려움이 발생할거 같았고 해결방안으로 검색 쿼리를 추가해주었다.
실제로, 공식문서를 참고해보면 검색어 쿼리를 넘겨줄때, 특정 필드를 추가할 수 있다고 안내하고 있고, 이에 따라 "intitle:", 과 "inauthor:" 필드를 추가해보았다.
그 결과, totalItems 수가 변하는 이슈가 해결이 되었다.
깃허브 이슈링크 에 자세히 적어두었다.
mvvm 패턴에 따라 적용하였다.
class BookTableViewHeaderView : UITableViewHeaderFooterView {
let totalCountLabel = UILabel()
let bottomBorder = UIView()
let searchTargetSegment = UISegmentedControl(items: ["책","작가"])
let disposeBag = DisposeBag()
override init(reuseIdentifier: String?) {
super.init(reuseIdentifier: reuseIdentifier)
setAttribute()
setLayout()
}
}
위으 코드와 같이 UITableViewHeaderFooterView
에 UISegmentedControl을 추가해 주었다.
struct BookTableHeaderViewModel {
let segmentIndex = BehaviorRelay<Int>(value: 0)
let selectedIndex : Observable<Int>
init() {
self.selectedIndex = segmentIndex
.asObservable()
}
}
selectedIndex
를 선언해주었다.다시 view 로 돌아와, view 와 view model 을 바인딩 해주었다.
func bind(_ viewModel : BookTableHeaderViewModel) {
self.searchTargetSegment.rx.selectedSegmentIndex
.bind(to: viewModel.segmentIndex)
.disposed(by: disposeBag)
}
우선, 네트워크 관련 부분이다.
// 검색어와, 검색타겟(책/작가) + startIndex 값을 받아, convertSearchQuery 를 통해 SearchQuery 형태로
let searchQueryStruct = Observable
.combineLatest(searchBarViewModel.shouldLoadResult, bookTableHeaderViewModel.selectedIndex, bookTableViewModel.fetchStratIndex, resultSelector: model.convertSearchQuery)
searchBarViewModel.shouldLoadResult
bookTableHeaderViewModel.selectedIndex
bookTableViewModel.fetchStratIndex
3가지 요소를 combineLatest 연산자를 활용해 model.convertSearchQuery
를 통해 원하는 struct 로 변하게끔 구현하였다.
model.convertSearchQuery
는 위의 3개의 요소를 받아 하나의 struct 로 변환해주는 함수 이다.let searchBookResult = searchQueryStruct
.flatMapLatest(model.searchBooks)
.share()
model.searchBooks
는 api통신을 가능하게 해주는 함수이다.전체코드는 깃허브 에서 확인 가능합니다.