Search code examples
iosobjective-cpromisekit

PromiseKit: How to do retry / polling in ObjC?


The PromiseKit "Common Patterns" docs are in Swift.

How can I write the retry / polling code in Objective C?

Retry / Polling

func attempt<T>(maximumRetryCount: Int = 3, delayBeforeRetry: DispatchTimeInterval = .seconds(2), _ body: @escaping () -> Promise<T>) -> Promise<T> {
    var attempts = 0
    func attempt() -> Promise<T> {
        attempts += 1
        return body().recover { error -> Promise<T> in
            guard attempts < maximumRetryCount else { throw error }
            return after(delayBeforeRetry).then(on: nil, attempt)
        }
    }
    return attempt()
}

attempt(maximumRetryCount: 3) {
    flakeyTask(parameters: foo)
}.then {
    //…
}.catch { _ in
    // we attempted three times but still failed
}

Solution

  • Answered by the PromiseKit developer on Github:

    - (AnyPromise *) attempt:(NSUInteger) maximumRetryCount delayBeforeRetry:(NSTimeInterval) delay provider:(AnyPromise* (^)()) provide {
        __block NSUInteger attempts = 0;
        AnyPromise *(^attempt)() = ^{
            attempts++;
            return provide().catch(^(id error) {
                if (attempts >= maximumRetryCount) @throw error;
                return PMKAfter(delay).then(attempt);
            });
        };
        return attempt();
    }
    

    Then, if you have a method like this:

    - (AnyPromise *) myPromise {
        return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
            ...
            resolve(nil) / resolve (error); 
        }];
    }
    

    Call it with

    [self attempt:3 delayBeforeRetry:2 provider:^{ return [self myPromise]; }]