はじめに
あまり発生しないケースかもしれないですが、 RxSwift の subscribe 内の処理を共通化したいと思ったことはないでしょうか。例えば、 API 通信でエラーが発生したらダイアログを出す処理や Firebase Crashlytics にエラー情報を送信する処理などです。その共通化の方法を実装する機会がありましたので、備忘録として残します。
実装
Observable の場合
共通処理を置いておく独自 Observer を用意します。そして、 subscribe の引数にその observer を入れるだけです。
SampleObserver.swift
import RxSwift
class SampleObserver<T> {
let onNext: ((T) -> Void)?
let onError: ((Error) -> Void)?
let onCompleted: (() -> Void)?
init(onNext: ((T) -> Void)? = nil,
onError: ((Error) -> Void)? = nil,
onCompleted: (() -> Void)? = nil) {
self.onNext = onNext
self.onError = onError
self.onCompleted = onCompleted
}
func handle(_ event: Event<T>) {
switch event {
case .next(let value):
// 共通処理を入れる
self.onNext?(value)
case .error(let error):
// 共通処理を入れる
self.onError?(error)
case .completed:
// 共通処理を入れる
self.onCompleted?()
}
}
}
SampleViewController.swift
import UIKit
import RxSwift
class SampleViewController: UIViewController {
let presenter: SamplePresenter
let disposeBag = DisposeBag()
override func viewDidLoad() {
super.viewDidLoad()
presenter.callAPI()
.subscribe(SampleObserver(
onNext: {[weak self] value in
// 独自の処理
},
onError: {[weak self] error in
// 独自の処理
}).handle)
.disposed(by: disposeBag)
}
}
Single や Completable の場合
ほぼ Observable と変わりませんが、 Single や Completable の場合の独自 Observer を載せておきます。
SampleSingleObserver.swift
import RxSwift
class SampleSingleObserver<T> {
let onSuccess: ((T) -> Void)?
let onError: ((Error) -> Void)?
init(onSuccess: ((T) -> Void)? = nil,
onError: ((Error) -> Void)? = nil) {
self.onSuccess = onSuccess
self.onError = onError
}
func handle(_ singleEvent: SingleEvent<T>) {
switch singleEvent {
case .success(let value):
// 共通処理を入れる
self.onSuccess?(value)
case .error(let error):
// 共通処理を入れる
self.onError?(error)
}
}
}
SampleCompletableObserver.swift
import RxSwift
class SampleCompletableObserver {
let onCompleted: (() -> Void)?
let onError: ((Error) -> Void)?
init(onCompleted: (() -> Void)? = nil,
onError: ((Error) -> Void)? = nil) {
self.onCompleted = onCompleted
self.onError = onError
}
func handle(_ completableEvent: CompletableEvent) {
switch completableEvent {
case .completed:
// 共通処理を入れる
self.onCompleted?()
case .error(let error):
// 共通処理を入れる
self.onError?(error)
}
}
}
まとめ
RxSwift の subscribe 内の処理を共通化する方法を書きました。私自身も人から教えてもらいそれを Swift で書き直したものですが、 独自 Observer を用意するという部分がミソなのかなと思います。同じような悩みを持つ方の助けになりましたら幸いです。