LoginSignup
6
8

More than 5 years have passed since last update.

「最大でn回のイベントを発行する + Completeしない」Observableの作り方

Last updated at Posted at 2017-05-09

RxSwiftを扱っていて、最大でn回のイベントを発行するCompleteしないObservableを使いたいときがある。例えば、API Call等の1回のみ行いたいタスクを行うために、下記の条件を満たしたObservableを扱いたい

  1. UIViewController.viewWillAppear(_:)に1回のみフックしてイベントを発行する
  2. Completeしない

1. UIViewController.viewWillAppear(_:)に1回のみフックしてイベントを発行する

1の条件を満たすために下記の2つの条件に分割する

1.1 UIViewController.viewWillAppear(_:)にフックするObservableを生成する
1.2 発行するイベントを1個のみにする

1.1 UIViewController.viewWillAppear(_:)にフックするObservableを生成する

extension Reactive where Base: UIViewController {
    var viewWillAppear: Observable<Void> {
        return sentMessage(#selector(UIViewController.viewWillAppear(_:))).map { _ in () }.shareReplay(1)
    }
}
viewController.rx.viewWillAppear
    .subscribe(...)
    .addDisposableTo(disposeBag)

上のように扱えるが、上の実装ではUIViewController.viewWillAppear(_:)が呼ばれる度にイベントが発行されてしまう

1.2 発行するイベントを1個のみにする

extension Reactive where Base: UIViewController {
    var viewWillAppear: Observable<Void> {
        return sentMessage(#selector(UIViewController.viewWillAppear(_:))).map { _ in () }.shareReplay(1)
    }

    var viewWillAppearOnce: Observable<Void> {
        return viewWillAppear.take(1)
    }
}

takeオペレータを使って、発行するイベントの回数を制御している

しかし、これだと下記のようにCompleteイベントも呼ばれてしまう

next()
complete

Subject等にbindingしているとCompleteイベントが流れてSubjectが終了してしまう。このようなケースは避けたい

2. Completeしない

extension Reactive where Base: UIViewController {
    var viewWillAppear: Observable<Void> {
        return sentMessage(#selector(UIViewController.viewWillAppear(_:))).map { _ in () }.shareReplay(1)
    }

    var viewWillAppearOnce: Observable<Void> {
        return Observable.concat ([viewWillAppear.take(1), Observable.never()])
    }
}

concatオペレータを用いて、CompleteしないObservable.never()とフィルタリングしているviewWillAppear.take(1)を結合して、下記の条件を満たしているObservableを実現している

  1. UIViewController.viewWillAppear(_:)に1回のみフックしてイベントを発行する
  2. Completeしない

参考文献

6
8
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
6
8