Search code examples
objective-cafnetworking-2

Wait for AFNetworking completion block before continuing (i.e. Synchronous)


I have a use case for AFNetworking to behave synchronously (details below). How can I achieve this?

Here is my code snippet, which I've simplified as much as possible.

I would like to return the success response, but I only ever get nil (because the function returns before the block is called).

- (id)sendForUrl:(NSURL *)url {
    AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
    __block id response;
    [manager GET:url.absoluteString parameters:nil success: ^(AFHTTPRequestOperation *operation, id responseObject) {
        response = responseObject;
        NSLog(@"JSON: %@", responseObject);
    } failure: ^(AFHTTPRequestOperation *operation, NSError *error) {
        NSLog(@"Error: %@", error);
    }];

    return response;
}

Details So the reason I need this to behave synchronously is because I am building a pod that will bootstrap an application at start up. The boot strapping hits a services and saves a bunch of values locally. These values are then used for the current session and not changed. If the values change, the user will get a strange experience, so its important I avoid this.

If the service is down, that's okay. We'll use default values or looks for some saved values from a previous session, but whatever happens, we don't want the experience for the user to change in the session.

(This is an engine for A/B testing and experimentation - if that helps you 'get' the use case).


Solution

  • It sounds like there's a part of your app that can't run until a starting request is done. But there's also a part that can run (like the part that starts the request). Give that part a UI that tells the user that we're busy getting ready. No blocking the UI.

    But if you must, and if AFNetworking doesn't provide a blocking version of a request (kudos to them for that), then you could always block the old fashioned way...

    - (void)pleaseDontUseThisIdea {
    
        __block BOOL thePopeIsCatholic = YES;
        [manager GET: ....^{
            // ...
            thePopeIsCatholic = NO;
        }];
    
        while (thePopeIsCatholic) {}
    }