I want to use Variable
in Rxswift to make caseResults search different Results with different boxId, like boxId == 1
get Results and boxId == 2
get another Results
class MainViewModel {
let cases: Driver<[CaseItemViewModel]>
let index = Variable<Int>(1)
init() {
let caseResults = realm.objects(RMCase.self)
.filter("boxId == \(index.value)")
.sorted(byKeyPath: "id", ascending: true)
self.cases = Observable.collection(from: caseResults)
.asDriverOnErrorJustComplete()
.map { results in results.map { CaseItemViewModel(with: $0) }}
}
}
class CaseItemViewModel {
let cased: RMCase
let id: Int
let boxId: Int
let name: String
init(with cased: RMCase) {
self.cased = cased
self.id = cased.id
self.boxId = cased.boxId
self.name = cased.name
}
}
In the ViewController
viewModel.boxs
.drive(tableView.rx.items(cellIdentifier: CellId.main.rawValue, cellType: MainTableViewCell.self)) { [weak self] row, item, cell in
guard let strongSelf = self else { return }
cell.setup(with: item)
// drive collectionView into tableViewCell
if let collectionView = cell.collectionView {
strongSelf.viewModel.cases.asObservable()
.bind(to:collectionView.rx.items(cellIdentifier: "testcell", cellType: MainCollectionViewCell.self)) { _row, _item, _cell in
_cell.setup(with: _item)
}
.disposed(by: cell.disposeBag)
}
}.disposed(by: disposeBag)
First of all, Variable
is deprecated, use BehaviorRelay
or BehaviorSubject
instead.
Change cases
to BehaviorRelay
so you don't have to initialise it in init
and then observe index
property and everytime it changes, bind new result to cases
like this:
let cases = BehaviorRelay<[CaseItemViewModel]>(value: [])
let index = BehaviorRelay<Int>(value: 1)
init() {
index
.flatMap { index -> Observable<Results<RMCase>> in
let caseResult = realm.objects(RMCase.self)
.filter("boxId == \(index)")
.sorted(byKeyPath: "id", ascending: true)
return Observable.collection(from: caseResult)
}
.map { results in results.map { CaseItemViewModel(with: $0) }}
.bind(to: cases)
.disposed(by: disposeBag)
}
In cases
you now always have array of CaseItemViewModel
and it will be filled with new values everytime index
changes.