Search code examples
iosswiftrx-swift

How can I wrap an async function with an Observable


I have an async function that currently looks something like this

func startLoginFlow() {
    IdentityProvider.shared.login { success, error in
        // on success a user has completed authentication
        if success {
            delegate?.userIsAuthenticated()
        }


        // on error something wen't wrong
        ....
    }
}

Essentially on success a delegate method is called and some action takes place as a result.

I'd like to wrap this as an observable instead. I do not have the option refactoring IdentityProvider.shared.login.

I essentially just need the observable to emit so I can subscribe and take action elsewhere using onNext.

I am currently doing the following

  func startLoginFlow() -> Observable<Void> {
        return Observable.create { [weak self] observable in
            IdentityProvider.shared.login { success, error in
                if success {
                    observable.onNext(Void())
                }
            }
            return Disposables.create()
        }
    }

Is this the best way to do this? I wasn't sure if I should use Observable.of and subscribe to the result of IdentityProvider.shared.login


Solution

  • This is how I create Observables as well. The only thing I would note is to add in the errors so you can handle your observables when it errors out, and the completion, as well, to signal that your observable is complete.

    func startLoginFlow() -> Observable<Void> {
            return Observable.create { [weak self] observable in
                IdentityProvider.shared.login { success, error in
                    if success {
                        observable.onNext(())
                        observable.onCompleted()
                    } else {
                        observable.onError(error)
                    }
                }
                return Disposables.create()
            }
        }
    

    Observable.of's work in this case as well. It just emits the completed method. You can test this out yourself, if you were trying to create an Observable<String>, with both methods.

    I find that doing Observable.create is beneficial here as you're doing network requests and that you can control how you want your observables to error, fail, or be completed.

    Someone here gave a pretty good example as well:

    Rxswift What difference between Observable.of and Observable<String>.create