Skip to content

Instantly share code, notes, and snippets.

@arashkashi
Last active August 16, 2022 10:25
Show Gist options
  • Save arashkashi/1ff6532f6993049f5b35e2d36d65f1a8 to your computer and use it in GitHub Desktop.
Save arashkashi/1ff6532f6993049f5b35e2d36d65f1a8 to your computer and use it in GitHub Desktop.
how to make a retry function on swift combine
import SwiftUI
import Combine
struct ContentView: View {
class ViewModel: ObservableObject {
var bag = Set<AnyCancellable>()
init() {
fetchFeeds()
.tryCatch({ err -> AnyPublisher<Int, Error> in
// if we throw here the retry will stop
if false {
throw err
}
// if we pass throw, the retry happens here.
return self.fetchFeeds()
})
.retry(10)
.sink { completion in
switch completion {
case .finished:
print("finished")
case .failure(let error):
print(error)
}
} receiveValue: { value in
print(value)
}.store(in: &bag)
}
var counter = 0
func fetchFeeds() -> AnyPublisher<Int, Error> {
return Future<Int, Error> { promise in
print(self.counter)
self.counter = self.counter + 1
return promise(.failure( NSError(domain: "Missing Feed URL", code: -10001, userInfo: nil)))
}
.eraseToAnyPublisher()
}
}
@ObservedObject var vm = ViewModel()
var body: some View {
Text("Hello, world!")
.padding()
}
}
extension Publisher {
func retryWithDelay<T, E>(times: Int)
-> Publishers.Catch<Self, AnyPublisher<T, E>> where T == Self.Output, E == Self.Failure
{
return self.catch { error -> AnyPublisher<T, E> in
return Publishers.Delay(
upstream: self,
interval: 3,
tolerance: 1,
scheduler: DispatchQueue.global()).retry(times).eraseToAnyPublisher()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment