LoginSignup
0
1

More than 1 year has passed since last update.

RxSwift の subscribe 内の処理を共通化する

Posted at

はじめに

あまり発生しないケースかもしれないですが、 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 を用意するという部分がミソなのかなと思います。同じような悩みを持つ方の助けになりましたら幸いです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1