I'm combining a viewDidAppear
and filter
Drivers with RxSwift. And they work great. But when I introduce a third Driver, it stops calling flatMapLatest
on the latest combine.
In my View Controller, I have these Drivers:
let filter: Driver<String>
let viewDidAppear: Driver<Void>
let refresh: Driver<Void>
And in my view model:
// On viewDidAppear, I download a list of portfolios
let viewDidAppearPortfolios = viewDidAppear
.flatMapLatest({ (_) -> Driver<Result<[PortfolioModel]>> in
return networkService.request(Router.portfolios)!
.responseCollections()
.trackActivity(fetching)
.asDriver(onErrorJustReturn: .failure(NSError()))
})
.flatMapLatest({ (result: Result<[PortfolioModel]>) -> Driver<[PortfolioModel]> in
switch result {
case .success(let value): return Driver.just(value)
case .failure(_): return Driver.just([])
}
})
// Then I combine with a filter from my search bar.
self.portfolios = Driver.combineLatest(viewDidAppearPortfolios, filter)
.flatMapLatest { (portfolios: [PortfolioModel], filter: String) -> Driver<[PortfolioModel]> in
if filter.isEmpty {
return Driver.just(portfolios)
}
return Driver.just(portfolios.filter({ (portfolio) -> Bool in
portfolio.portfolio.localizedCaseInsensitiveContains(filter)
}))
}
The above works!
The network requests a list of portfolios, and I'm able to filter those results as I type, client side.
However, I'd like for the user to pull to refresh, and trigger the network request again! And so, I combine with my refresh driver.
And this:
Driver.combineLatest(viewDidAppearPortfolios, filter)
Becomes this:
Driver.combineLatest(viewDidAppearPortfolios, filter, refresh)
Problem!
After combining with refresh
the flatMapLatest
is no longer called on viewDidAppear! Only if I manually pullToRefresh.
Driver.combineLatest(viewDidAppearPortfolios, filter, refresh).flatMapLatest { _,_,_ in
// No longer get's called on viewDidAppear after combining with refresh
}
viewDidAppearPortfolios
still executes, so the network request
is getting called! Any idea why?
Thank you!
In contrast to RxSwift, Combine also allows subscribers to request more values at any time, resulting in backpressure support. So, rather than the publisher deciding when values are propagated, it is actually the subscriber demanding new values.
RxSwift: Driver Go from: a single observable that updates the entire UI to bindTo and reuse the same observable across the viewController.
It looks like your refresh
didn't emit a single event yet and so the combineLatest
is not computed.
I tried this code to test:
let one = Driver.just(1)
let two = Driver.just(2)
let three: Driver<Int> = .just(3)
let result = Driver.combineLatest(one, two, three)
.flatMapLatest {
return Driver.just($0 + $1 + $2)
}
result.drive(onNext: {
print($0)
})
This prints 6 but if you use let three: Driver<Int> = .empty()
this is not printing anything. So I guess you need a way to set an initial value to refresh
stream.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With