import Foundation import PromiseKit /// Attempt and retry a task that fails with resume data up to `maximumRetryCount` times func attemptResumableTask( maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping (Data?) -> Promise ) -> Promise { var attempts = 0 func attempt(with resumeData: Data? = nil) -> Promise { attempts += 1 return body(resumeData).recover { error -> Promise in guard attempts < maximumRetryCount, let resumeData = (error as NSError).userInfo[NSURLSessionDownloadTaskResumeData] as? Data else { throw error } return after(delayBeforeRetry).then(on: nil) { attempt(with: resumeData) } } } return attempt() } /// Attempt and retry a task up to `maximumRetryCount` times func attemptRetryableTask( maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping () -> Promise ) -> Promise { var attempts = 0 func attempt() -> Promise { attempts += 1 return body().recover { error -> Promise in guard attempts < maximumRetryCount else { throw error } return after(delayBeforeRetry).then(on: nil) { attempt() } } } return attempt() }