I am starting my first RxSwift project for an iOS application and learn about reactive programming.
While the idea is quite simple: the user searches for movies that match the text of the search bar, this causes a query that populates the UITableView with results. Using the tutorials and examples found on the Internet, I was able to implement this bit without any problems.
The hard part comes up when I try to load the next page of results caused by scrolling the bottom of the table view.
Here is the code used so far:
public final class HomeViewModel: NSObject { // MARK: - Properties var searchText: Variable<String> = Variable("") var loadNextPage: Variable<Void> = Variable() lazy var pages: Observable<PaginatedList<Film>> = self.setupPages() // MARK: - Reactive Setup fileprivate func setupPages() -> Observable<PaginatedList<Film>> { return self.searchText .asObservable() .debounce(0.3, scheduler: MainScheduler.instance) .distinctUntilChanged() .flatMapLatest { (query) -> Observable<PaginatedList<Film>> in return TMDbAPI.Films(withTitle: query, atPage: 0) } .shareReplay(1) } }
Here's what I still have: the observed pages bound to my table view in the HomeViewController , and the text of its search string is bound to searchText .
I use Alamofire to make API calls backstage, and TMDbAPI.Films(withTitle: query) returns the Observed number of broken lists.
Here is my PaginatedList model structure
public struct PaginatedList<T> { // MARK: - Properties let page: Int let totalResults: Int let totalPages: Int let results: [T] // MARK: - Initializer init(page: Int, totalResults: Int, totalPages: Int, results: [T]) { self.page = page self.totalResults = totalResults self.totalPages = totalPages self.results = results } // MARK: - Helper functions / properties var count: Int { return self.results.count } var nextPage: Int? { let nextPage = self.page + 1 guard nextPage < self.totalPages else { return nil } return nextPage } static func Empty() -> PaginatedList { return PaginatedList(page: 0, totalResults: 0, totalPages: 0, results: []) } } extension PaginatedList { // MARK: - Subscript subscript(index: Int) -> T { return self.results[index] } }
Now I'm looking for a reactive way to bind my variable loadNextPage to the observable from the broken lists so that it calls up the next page. And when the text of the search bar changes, pagination will reset to 0.
I believe that using scan and concat would be necessary, but I'm still not sure how ...
Any suggestions on how to achieve this would be greatly appreciated ...