Reputation: 2259
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
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
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