Below I have enum representing State of a UITableView. The states are divided into 3 categories as below.
For all the 3 states I have different UITableViewCells which will be shown for respected cases.
So for fetchMovies input, I am actually checking the movies count and emitting the state & once again after the result.
Can the code written in transform
be further reduced or any suggestions.
You can find the architecture here CleanArchitectureRxSwift
import Foundation
import RxSwift
import RxCocoa
protocol ViewModelType {
associatedtype Input
associatedtype Output
func transform(input: Input) -> Output
}
enum MoviesViewModelState {
case loading
case loaded([String])
case loadRemaining
}
class MoviesViewModel: ViewModelType {
deinit {
print("HomeViewModel deinit")
}
struct Input {
let fetchMovies: Driver<Void>
}
struct Output {
let movieSection: Driver<MoviesViewModelState>
}
var repository: SyncRepository
private var names: [String] = []
private let disposeBag = DisposeBag()
init(repository: SyncRepository) {
self.repository = repository
}
func transform(input: Input) -> Output {
let movieSection = PublishSubject<MoviesViewModelState>()
input.fetchMovies
.asObservable()
.flatMapLatest { [unowned self] _ -> Observable<[String]> in
if self.names.count > 0 {
movieSection.onNext(.loadRemaining)
} else {
movieSection.onNext(.loading)
}
return self.repository.fetchNames(for: self.names.count) // returns Observable<[String]>
}.subscribe(onNext: { [unowned self] (names: [String]) in
self.names.append(contentsOf: names)
movieSection.onNext(.loaded(self.names))
}).disposed(by: disposeBag)
return Output(movieSection: movieSection.asDriverOnErrorJustComplete())
}
}
extension ObservableType {
func asDriverOnErrorJustComplete() -> Driver<Element> {
return asDriver { _ in
return Driver.empty()
}
}
}