Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I use retry/polling in ObjC? #1043

Closed
thomers opened this issue Apr 5, 2019 · 6 comments
Closed

How can I use retry/polling in ObjC? #1043

thomers opened this issue Apr 5, 2019 · 6 comments

Comments

@thomers
Copy link

thomers commented Apr 5, 2019

How would I write this attempt method from the docs in ObjC?

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
}

I have read the comments in #350 (comment) about catch behaving the same as recover, but I'm struggling with translating it into ObjC.

Thanks!


  • Please specify the PromiseKit major version you are using

PromiseKit 4.5.2 (mainly because I'm not sure about changes to Obj-C support in later versions)

  • Please specify how you installed PromiseKit

Cocoapods 1.5.3

@mxcl
Copy link
Owner

mxcl commented Apr 5, 2019

- (void)attempt:(int)maximumRetryCount, delay:(NSTimeInterval)delay provider:(PMKPromise* (^)()) {
    __block int attempts = 0;
    PMKPromise *(^attempt)() = ^{
        attempts++;
        return provide().catch(^(id error) {
            if (attempts >= maximmumRetryCount) @throw error;
            return PMKAfter(delay).then(attempt);
        })
    };
    return attempt()
} 

My objc is rusty so may not compile.

@mxcl
Copy link
Owner

mxcl commented Apr 5, 2019

mainly because I'm not sure about changes to Obj-C support in later versions

6 is the same as 4 for objc. No need to upgrade, but we don't typically back port fixes to v4.

@thomers
Copy link
Author

thomers commented Apr 5, 2019

Wow, that is some serious block syntax action going on.

I got it to compile with these modifications:

- (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();
}

Does this look right?

I got these warnings:

On the empty () in the method signature provider:(AnyPromise* (^)()) provide {
"This block declaration is not a prototype."

On AnyPromise *(^attempt)() = ^{ :
"Block pointer variable 'attempt' is unintialized when captured by block."

EDIT: Also, how do I call the attempt method correctly with this method:

- (AnyPromise *) fetchIdentityId {
	return [AnyPromise promiseWithResolverBlock:^(PMKResolver resolve) {
		[[[AWSMobileClientHelper sharedAWSMobileClient] getIdentityId] continueWithBlock:^id _Nullable(AWSTask<NSString *> * _Nonnull task) {
			if(!task.error){
				resolve(nil);
			} else {
				resolve(task.error);
			}
			return nil;
		}];
	}];
}

Thanks so much for your help and your work on such an awesome library!

@mxcl
Copy link
Owner

mxcl commented Apr 6, 2019

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

@mxcl
Copy link
Owner

mxcl commented Apr 6, 2019

Like you could probably use a selector rather than a block. It's been a long time since I did any objc.

@thomers
Copy link
Author

thomers commented Apr 7, 2019

Perfect! Again, thank you!

@thomers thomers closed this as completed Apr 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants