I have the following code in RxSwift 4.0-based project:
private var _myRelay = PublishRelay<MyData>()
var myRelay: Observable<MyData> {
return _myRelay.asObservable()
}
Now I need to keep the last value (if any) in _myRelay
, so I decided to convert it to BehaviorRelay
:
private var _myRelay = BehaviorRelay<MyData?>(value: nil)
I want to keep public interface intact
var myRelay: Observable<MyData>
I mean I do not want to convert it to
var myRelay: Observable<MyData?>
The idea is not to "publish" initial value == nil
to subscribers of myRelay
, and start publishing only after some data appears. How can I do it? I am completely beginner in Rx, but I am sure there should be some elegant solution.
The simplest solution is to filter out the nils. If you were using 5.0 then you would do that with compactMap
but since you said 4.0 that means you will need a filter and map:
var myRelay: Observable<MyData> {
return _myRelay.filter { $0 != nil }.map { $0! }.asObservable()
}
but you might actually be better off using a ReplaySubject
instead of a Relay.
private let _myRelay = ReplaySubject<MyData>.create(bufferSize: 1)
var myRelay: Observable<MyData> {
return _myRelay.asObservable()
}
That way, you don't have to deal with nils at all. (Also note, _myRelay
should be a let
not a var.)
Doing the above will also allow you to emit a completed
event when the observable goes out of scope (a relay doesn't allow that.)
private let _myRelay = ReplaySubject<MyData>.create(bufferSize: 1)
var myRelay: Observable<MyData> {
return _myRelay.asObservable()
}
deinit {
_myRelay.onCompleted()
}