Nikita Ermolenko
Nikita Ermolenko

Reputation: 2259

Delay for Retry - RxSwift

Is there elegant solution for creating delay for retry? When error occurs I want to wait for 5 seconds and restart Observable (retry)

Upvotes: 2

Views: 5769

Answers (2)

chandan thakur
chandan thakur

Reputation: 51

Here is the code for swift 4.0+

// sample retry function with delay
private func sampleRetryWithDelay(){
    let maxRetry = 3
    let retryDelay = 1.0 // seconds
    let _ = sampleStreamWithErrors() // sample observable stream, replace with the required observable
        .retryWhen { errors in
            return errors.enumerated().flatMap{ (index, error) -> Observable<Int64> in
                return index < maxRetry ? Observable<Int64>.timer(RxTimeInterval(retryDelay), scheduler: MainScheduler.instance) : Observable.error(error)
            }
        }.subscribe(onNext:{ value in
            print("Result:\(value)")
        })
}

// Sample stream with errors, helper function only - generating errors 70% of the time
private func sampleStreamWithErrors() -> Observable<Int>{
    return Observable.create { observer in
        let disposable = Disposables.create() {} // nothing to cancel, we let it complete
        let randomInt = Int(arc4random_uniform(100) + 1)
        if randomInt > 70 {
            observer.on(.next(randomInt))
            observer.on(.completed)
        } else {
            let sampleError = NSError(domain: "SampleDomain", code: randomInt, userInfo: nil)
            print("Result:Error:\(randomInt)")
            observer.on(.error(sampleError))
        }
       
        return disposable
    }
}

Upvotes: 4

Hlung
Hlung

Reputation: 14298

Just create a PrimitiveSequence extension that wraps around retry(). (Swift5.1 RxSwift 4.3.1)

extension PrimitiveSequence{
  func retry(maxAttempts: Int, delay: TimeInterval) -> PrimitiveSequence<Trait, Element> {
    return self.retryWhen { errors in
      return errors.enumerated().flatMap{ (index, error) -> Observable<Int64> in
        if index < maxAttempts {
          return Observable<Int64>.timer(RxTimeInterval(delay), scheduler: MainScheduler.instance)
        } else {
          return Observable.error(error)
        }
      }
    }
  }
}

Usage example: (retry 3 times, with 2 sec delay each)

yourRxStream.retry(maxAttempts: 3, delay: 2)

Upvotes: 5

Related Questions