LoGary LoGary - 1 year ago 148
Swift Question

RxSwift unwrap optional handy function?

Currently I have created a function

to safely unwrap the optional input in the stream.

func unwrapOptional<T>(x: Optional<T>) -> Observable<T> {
return x.map(Observable.just) ?? Observable.empty()

let aOpt: String? = "aOpt"
_ = Observable.of(aOpt).flatMap(unwrapOptional).subscribeNext { x in print(x)}

let aNil: String? = nil
_ = Observable.of(aNil).flatMap(unwrapOptional).subscribeNext { x in print(x)}

let a: String = "a"
_ = Observable.of(a).flatMap(unwrapOptional).subscribeNext { x in print(x)}

// output

What I want to archive is to create a handy function instead of using
, for example


Something I tried to do, but it never compiles...

extension ObservableType {
func unwrapOptional<O : ObservableConvertibleType>() -> RxSwift.Observable<O.E> {
return self.flatMap(unwrapOptional)

Answer Source

You want the unwrapOptional method to only work on observables that have optional type.

So you somehow have to constraint the Element of Observable to conform to the Optional protocol.

extension Observable where Element: OptionalType {
    /// Returns an Observable where the nil values from the original Observable are
    /// skipped
    func unwrappedOptional() -> Observable<Element.Wrapped> {
        return self.filter { $0.asOptional != nil }.map { $0.asOptional! }

Unfortunately, Swift does not define such a protocol (OptionalType). So you also need to define it yourself

/// Represent an optional value
/// This is needed to restrict our Observable extension to Observable that generate
/// .Next events with Optional payload
protocol OptionalType {
    associatedtype Wrapped
    var asOptional:  Wrapped? { get }

/// Implementation of the OptionalType protocol by the Optional type
extension Optional: OptionalType {
    var asOptional: Wrapped? { return self }
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download