Are AFNetworking success/failure blocks invoked on the main thread?

16,603

Solution 1

In AFNetworking 2, AFHTTPRequestOperationManager has a completionQueue property.

The dispatch queue for the completionBlock of request operations. If NULL (default), the main queue is used.

    #if OS_OBJECT_USE_OBJC
    @property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;
    #else
    @property (nonatomic, assign, nullable) dispatch_queue_t completionQueue;
    #endif

In AFNetworking 3, the completionQueue property has been moved to AFURLSessionManager (which AFHTTPSessionManager extends).

The dispatch queue for completionBlock. If NULL (default), the main queue is used.

@property (nonatomic, strong) dispatch_queue_t completionQueue;
@property (nonatomic, strong, nullable) dispatch_queue_t completionQueue;

Solution 2

They are invoked on the main queue, unless you explictly sets the queue on AFHTTPRequestOperation, as shown in setCompletionBlockWithSuccess:failure from AFHTTPRequestOperation.m

self.completionBlock = ^{
    if (self.error) {
        if (failure) {
            dispatch_async(self.failureCallbackQueue ?: dispatch_get_main_queue(), ^{
                failure(self, self.error);
            });
        }
    } else {
        if (success) {
            dispatch_async(self.successCallbackQueue ?: dispatch_get_main_queue(), ^{
                success(self, self.responseData);
            });
        }
    }
};

Solution 3

As everyone explained, it's in the source code of the AFNetworking, as for the way to do it,

AFNetworking 2.xx:

// Create dispatch_queue_t with your name and DISPATCH_QUEUE_SERIAL as for the flag
dispatch_queue_t myQueue = dispatch_queue_create("com.CompanyName.AppName.methodTest", DISPATCH_QUEUE_SERIAL);

// init AFHTTPRequestOperation of AFNetworking
operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

// Set the FMDB property to run off the main thread
[operation setCompletionQueue:myQueue];

AFNetworking 3.xx:

AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] init];
[self setCompletionQueue:myQueue];

Solution 4

You can set the completion callback queue by specifying completionGroup, completionQueue see the AFNetworking API document

Share:
16,603
thomasd
Author by

thomasd

Updated on June 22, 2022

Comments

  • thomasd
    thomasd about 2 years

    Does AFNetworking call the completion block on the main thread? or is it called in the background, requiring me to manually dispatch my UI updates to the main thread?

    Using code instead of words, this is the example code from the AFNetworking documentation with the call to NSLog replaced by a UI update:

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        self.label.text = JSON[@"text"];
    } failure:nil];
    

    Should it be written like this instead?

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
        dispatch_async(dispatch_get_main_queue(), ^{
            self.label.text = JSON[@"text"];
        });
    } failure:nil];
    
  • Ben Coffman
    Ben Coffman about 11 years
    Good to know probably should have checked and not assumed they just executed them on the same thread as the request
  • thomasd
    thomasd over 8 years
    I agree! I edited the answer to include AFNetworking 3 and to add links to the source of both versions.
  • onmyway133
    onmyway133 over 8 years
    @thomasd thanks. There are some rejections on your edit, so I can't accept it, but I just copied it again.