[Swift]Observable(RxSwift) - Promise(PromiseKit)相互変換


この記事ではSwiftで非同期な処理を扱う際に便利なライブラリであるRxSwiftとPromiseKitをプロジェクト内で両方導入している際に連携を取る方法について説明します。
導入するにしても大抵は片方しか使わないですが、両者が混在するプロジェクトに向き合わなければならない局面は人生においてあったりなかったりします。
使用ライブラリとバージョンは以下になります。

https://github.com/ReactiveX/RxSwift (4.3.1)
https://github.com/mxcl/PromiseKit (6.8.3)

ライブラリのインストール手順等については他の方の記事を参照という次第でよろしくおねがいします。

Observable->Promise変換

ObservableをPromiseで使える。Promiseの都合上結果は1度しか受け取れないのでそのようになっています


import PromiseKit
import RxSwift

extension Observable {
    func toPromise() -> Promise<Element> {
        var disposable: Disposable?
        return Promise { resolver in
            disposable = take(1)
                .subscribe(
                    onNext: { value in resolver.fulfill(value) },
                    onError: { resolver.reject($0) },
                    onCompleted: { disposable?.dispose() }
            )
        }
    }
}

Promise->Observable変換

この変換方式では1度値が流れるとonCompletedを発するので、RxSwiftで継続して値を受け取るにはflatMap等でラップする必要があります

import PromiseKit
import RxSwift

extension Promise {
    func toObservable() -> Observable<T> {
        return Observable.create { observer -> Disposable in
            self.done { observer.onNext($0) }
                .catch { observer.onError($0) }
                .finally { observer.onCompleted() }
            return Disposables.create()
        }
    }
}