はじめに
エラーが流れてきたときに指定回数、指定条件でリトライする処理は標準オペレータとして提供されており、 retry
もしくは retryWhen
を利用します。
今回はこのようなエラーが流れてきたときではなく、「nil だったとき」のような独自のリトライトリガーを実現する方法をご紹介します。
方針
- flatMap で特定条件時に独自のエラーに変換する
- flatMap の中で timer で遅延させて自身を再帰的に呼び出す
ザッとこの2パターンを思いつきました。
1に関しては、リトライ処理のためにエラーを新しく定義するのはどうなのかという点、2はリトライ回数を制御するためにグローバル変数を定義する必要がある点が個人的に感じた悩みポイントです。
実装環境に合わせた判断と工夫を追加で施していただければと思います。
1. エラーに変換してリトライ
enum CustomeError: Error {
case nilData
}
private func fetch() -> Observable<Data> {
API.fetch()
.flatMap { res -> Observable<Data> in
guard let data = res else {
return .error(CustomeError.nilData)
}
return .just(data)
}
.retry(3) // 標準オペレータの利用
}
2. 再帰処理を利用してリトライ
private func fetch() -> Observable<Data> {
API.fetch()
.flatMap { res -> Observable<Data> in
guard let data = res else {
// 5 秒間隔でリトライ
return Observable<Int>.timer(.seconds(5), scheduler: MainScheduler.instance)
.flatMap { [unowned self] _ in
// リトライ回数を制御する場合はここで判定
self.fetch() // 再帰
}
}
return .just(data)
}
}
おわりに
RxSwift の利用方法メモとして書いてみました。
ご指摘等ございましたら、コメント頂けますと幸いです。