[iOS] RxSwiftのIntervalオペレータを使用して一定間隔で処理を行う

本記事では、RxSwiftのIntervalオペレータを使用して一定間隔で処理を行う実装を紹介します。例えば、特定のAPIから定期的に情報を取得したい場合などに使用できます。
2021.03.05

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

CX事業本部の平屋です。

本記事では、RxSwiftIntervalオペレータを使用して一定間隔で処理を行う実装を紹介します。例えば、特定のAPIから定期的に情報を取得したい場合などに使用できます。

RxSwift自体の解説については、公式リポジトリや入門記事などを参照してください。

検証環境

  • macOS Catalina 10.15.6
  • Xcode Version 12.4
  • RxSwift 6.0.0

実装

さっそく実装を紹介していきます。

以下のサンプルは、1秒ごとにカウントをログ出力してカウントアップするコードで、一定間隔で処理を行う仕組みを作るためだけにRxSwiftを使用しています。

ObservableTypeinterval(_:scheduler:)を使用して、一定間隔でObservableを生成するようにし、subscribe(_:)で購読します。一定間隔で行いたい処理はsubscribe(_:)の引数のクロージャ内に記述します。

また、Disposable.dispose()を使用して購読を破棄すれば、任意のタイミングで処理を止めることができます。

import UIKit
import RxSwift

class ViewController: UIViewController {
    private let disposeBag = DisposeBag()
    private var subscription: Disposable?
    var count = 1

    override func viewDidLoad() {
        super.viewDidLoad()
        print("viewDidLoad")

        // 実行間隔:1秒を定義する
        let period = DispatchTimeInterval.seconds(1)

        let subscription = Observable<Int>
            .interval(period, scheduler: MainScheduler.instance) // 一定間隔でObservableを生成
            .subscribe { _ in // 購読する
                // 一定間隔で行いたい処理をここに追加する
                // 本サンプルではカウントをログ出力し、カウントアップする
                print(self.count)
                self.count += 1
            }

        self.subscription = subscription
        disposeBag.insert(subscription)

        // 処理を止めたい場合は購読を破棄する
        // subscription.dispose()
    }
}

上記サンプルでは、購読後1秒後に初回の処理が実行されますが、以下のようにstartWith(_:)を使用すれば、初回の処理を即時に実行できます。

Observable<Int>
    .interval(period, scheduler: MainScheduler.instance)
    .startWith(0) // <- 追加!
    .subscribe { _ in
        // ...
    }.disposed(by: disposeBag)

動作確認

サンプルコードを実行すると、以下のように1秒ごとにカウントがログ出力されます。

1
2
3
4
5
6
7
8
9
10
(続く...)

さいごに

本記事では、RxSwiftIntervalオペレータを使用して一定間隔で処理を行う実装を紹介しました。どなたかの参考になれば幸いです。

参考資料