Reputation: 438
For my app, I have to connect to two webservices that return JSON.
I first rolled my own networking code using GCD, but seeing how AFNetworking handles things, I decided to implement it. Most things went ok, but at some point I'm retrieving two arrays filled with objects. Those two arrays are then compared using a different method. Somehow the actual enqueueing is either delayed or not working, depending on the code I'm using.
When using:
NSArray *operations = [NSArray arrayWithObjects:operation, operation1, nil];
AFHTTPClient *client = [[AFHTTPClient alloc]init];
[client enqueueBatchOfHTTPRequestOperations:operations progressBlock:nil completionBlock:^(NSArray *operations) {
[self compareArrays:self];
}
it just hangs.
When using:
[operation start];
[operation1 start];
[operation waitUntilFinished];
[operation1 waitUntilFinished];
[self compareArrays:self];
at the end, it gets the arrays, but only compares after the UI has been formed.
EDIT:
I checked Dave's answer, and it looks really streamlined.
Would my app benefit from using the AFHTTPClient
, or does this method (using AFJSONRequestOperation
) offer the same features? I recall AFHTTPClient
handling reachability on its own now (though you need to set it). I fiddled around a bit, and got this working:
NSOperationQueue *queue = [[NSOperationQueue alloc]init];
WebServiceStore *wss = [WebServiceStore sharedWebServiceStore];
self.userData = wss.userData;
serviceURL = [NSString stringWithFormat: @"WEBSERVICE URL"];
NSString* zoekFruit = [NSString stringWithFormat:
@"%@?customer=%@&gebruiker=%@&password=%@&breedte=%@&hoogte=%@&diameter=%@",
serviceURL,
self.userData.Klant,
self.userData.Gebruiker,
self.userData.Wachtwoord,
breedte,
hoogte,
diameter];
NSURL *url = [NSURL URLWithString:[zoekFruit stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
id results = [JSON valueForKey:@"data"];
[results enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
//Initiate the BWBand
BWBand *band = [[BWBand alloc]init];
//Set the BWBand's properties with valueforKey (or so).
[getBandenArray addObject:band];
}];
NSLog(@"getBandenArray: %@",getBandenArray);
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Error" message:@"Error retrieving Banden" delegate:self cancelButtonTitle:@"Cancel" otherButtonTitles:@"Ok", nil];
[alert show];
}];
[queue addOperation:operation];
Upvotes: 2
Views: 2935
Reputation: 7717
The AFNetworking class will allow you to create a bunch of operations, then hand them all off to be processed. You add some code to occur on success/failure for each individual request and/or when all requests have been processed.
Here's an outline of what you might do. I'll leave the details, actual comparison, and error handling to your imagination. :)
-(void)fetchAllTheData {
NSMutableArray * operations = [NSMutableArray array];
for (NSString * url in self.urlsToFetchArray) {
[operations addObject:[self operationToFetchSomeJSON:url]];
}
AFHTTPClient *client = [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:[PREFS objectForKey:@"categoryUrlBase"]]];
[client enqueueBatchOfHTTPRequestOperations:operations
progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
NSLog(@"Finished %d of %d", numberOfFinishedOperations, totalNumberOfOperations);
}
completionBlock:^(NSArray *operations) {
DLog(@"All operations finished");
[[NSNotificationCenter defaultCenter] postNotificationName:@"Compare Everything" object:nil];
}];
}
-(AFHTTPRequestOperation *)operationToFetchSomeJSON:(NSString*)whichOne {
NSURL * jsonURL = [NSURL URLWithString:whichOne];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:jsonURL];
[request setHTTPShouldHandleCookies:NO];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
NSLog(@"My data = %@", operation.responseString); // or responseData
// Got the data; save it off.
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
DLog(@"Error downloading: %@ %@", whichOne, error);
}];
return operation;
}
Hope that helps.
Upvotes: 4