Xaree Lee
Xaree Lee

Reputation: 3387

How to using AFNetworking 2.0 library synchronously?

The following code using AFNetworking 2.0 is valid to fetch data through internet:

NSString *URLPath = @"http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=json";
NSDictionary *parameters = nil;

[[AFHTTPRequestOperationManager manager] GET:URLPath parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"success: %@", responseObject);

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"failure: %@", error);
}];

But I want to test those requests synchronously in the unit test. But it would be blocked when using GCD semaphore like this:

// This code would be blocked.
dispatch_semaphore_t sema = dispatch_semaphore_create(0);

NSString *URLPath = @"http://www.raywenderlich.com/downloads/weather_sample/weather.php?format=json";
NSDictionary *parameters = nil;

[[AFHTTPRequestOperationManager manager] GET:URLPath parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"success: %@", responseObject);
    dispatch_semaphore_signal(sema);

} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"failure: %@", error);
    dispatch_semaphore_signal(sema);

}];

dispatch_semaphore_wait(sema, DISPATCH_TIME_FOREVER);
dispatch_release_ARC_compatible(sema);

How can I fetch data using AFNetworking 2.0 library synchronously (test those code in Kiwi)?

Upvotes: 0

Views: 2120

Answers (1)

gregschlom
gregschlom

Reputation: 4965

Your semaphore would be blocked because by default AFNetworking runs on the main loop. So if you're waiting on the main loop for the semaphore, AFNetworking's code never gets to run.

In order to fix this, you simply have to tell AFNetworking to use a different dispatch queue. You do that by setting the operationQueue property on AFHTTPRequestOperationManager

You can create your own dispatch queue, or use one of the predefined ones, like so:

// Make sure that the callbacks are not called from the main queue, otherwise we would deadlock
manager.operationQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

Upvotes: 1

Related Questions