Search code examples
swiftreactive-programmingrx-swift

Combining two Observable<Void>s


I'm still a reactive newbie and I'm looking for help.

func doA() -> Observable<Void>
func doB() -> Observable<Void>

enum Result {
    case Success
    case BFailed
}

func doIt() -> Observable<Result> {

    // start both doA and doB. 
    // If both complete then emit .Success and complete
    // If doA completes, but doB errors emit .BFailed and complete
    // If both error then error

}

The above is what I think I want... The initial functions doA() and doB() wrap network calls so they will both emit one signal and then Complete (or Error without emitting any Next events.) If doA() completes but doB() errors, I want doIt() to emit .BFailed and then complete.

It feels like I should be using zip or combineLatest but I'm not sure how to know which sequence failed if I do that. I'm also pretty sure that catchError is part of the solution, but I'm not sure exactly where to put it.

--

As I'm thinking about it, I'm okay with the calls happening sequentially. That might even be better...

IE:

Start doA() 
    if it completes start doB() 
        if it completes emit .Success 
        else emit .BFailed.
    else forward the error.

Thanks for any help.


Solution

  • I've learned RxSwift well enough to answer this question now...

    func doIt() -> Observable<Result> {
        Observable.zip(
            doA().map { Result.Success },
            doB().map { Result.Success }
                .catch { _ in Observable.just(Result.BFailed) }
        ) { $1 }
    }