I have a Subject
observable representing the result of the network request that needs to be delivered to multiple subscribers.
I can use ReplaySubject
of buffer 1 and publish()
method. However, the network request gets executed only once.
I'd like to trigger the fetch event at any give point in the future. How can I trigger a new requst?
Currently, I have a Service
object that holds the ReplaySubject
and has a method reload()
which triggers the network request and publishes the result to the aReplaySubject
.
Is there any method on Observable
that can "refresh" it and deliver a new value to all the current subscribers?
If I'm interpreting this question correctly, this is a fairly common problem in RxSwift. You need to be able to recreate your network request Observable
each time your fetch is "triggered," but you need these results delivered on a single Observable
that only gets created once, and has multiple subscribers. This is done with a flatMap
:
struct Service {
var resultsObservable: Observable<Results> {
return resultsSubject.asObservable()
}
private let resultsSubject: ReplaySubject<Results> = .create(bufferSize: 1)
private let reloadSubject = PublishSubject<Void>()
private let disposeBag = DisposeBag()
init() {
bindFetch()
}
func reload() {
reloadSubject.onNext(())
}
private func bindFetch() {
reloadSubject
.asObservable()
.flatMap(fetch)
.bind(to: resultsSubject)
.disposed(by: disposeBag)
}
private func fetch() -> Observable<Results> {
// URLSession just one example
let urlRequest = URLRequest(url: URL(string: "https://apple.com")!)
return URLSession
.shared
.rx
.data(request: urlRequest)
.map(Results.init)
.catchErrorJustReturn(Results.empty())
}
}
In this example, you can subscribe to resultsObservable
multiple times, and each should be updated after a new reload()
occurs.