Reputation: 1535
I searched a lot and saw a few answers but I still not sure how to solve it: I want to execute some void function only when operation is done.
My code:
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[request setHTTPBody:[soapBody dataUsingEncoding:NSUTF8StringEncoding]];
[request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPMethod:@"POST"];
[request addValue:kAPP_PASSWORD_VALUE forHTTPHeaderField:kAPP_PASSWORD_HEADER];
[request addValue:@"http://blablabla" forHTTPHeaderField:@"SOAPAction"];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
self.responseXML = [operation responseString];
NSData *data = [self.responseXML dataUsingEncoding:NSUTF8StringEncoding];
[self doParse:data];
self.numOfWallPosts = [self.sharedPrefs integerForKey:@"total_number_of_wall_posts"];
for (int i = 1; i <= self.numOfWallPosts; i++)
{
NSString *sharedKey = [NSString stringWithFormat:@"wall_number_%d", i];
NSMutableDictionary *aaa = [[NSMutableDictionary alloc] init];
aaa = [self.sharedPrefs objectForKey:sharedKey];
[self handleWallPostsWithWallPost:aaa];
}
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"\n\nError: %@", error);
}];
[operation start];
[self handleWallPostsWithWallPost:aaa];
- Downloading a few images in background, so, the block is done, but in background, there is a few images downloading.
How should I know when the images downloading is done?
- (void)handleWallPostsWithWallPost:(NSMutableDictionary *)wallPost
{
NSMutableDictionary *temp = [[NSMutableDictionary alloc] init];
temp = wallPost;
NSString *owner = [temp objectForKey:@"owner"];
NSString *title = [temp objectForKey:@"title"];
NSString *imageUrl = [temp objectForKey:@"image_url"];
NSInteger wallId = [[temp objectForKey:@"wall_id"] integerValue];
NSLog(@"Wall ID: %d | Owner: %@ | Title: %@ | Image URL: %@", wallId, owner, title, imageUrl);
// arrayOfOwnersImage - Save as NSData
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:imageUrl]];
AFImageRequestOperation *operation;
operation = [AFImageRequestOperation imageRequestOperationWithRequest:request imageProcessingBlock:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
NSLog(@"Image downloaded...");
NSData *imageData = UIImageJPEGRepresentation(image, 90);
[self.arrayOfOwnersImage addObject:imageData];
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"Image download fail: %@", [error localizedDescription]);
}];
[operation start];
}
Any ideas?
Upvotes: 0
Views: 398
Reputation: 33428
I think you should follow two different ways to achieve this.
First simple way. Use a counter. Set up the counter with the number of operations you need to run. When an operation finishes the counter will be decremented. When it's zero, operations are completed. Be sure to decrement the counter in the completion block of a operation and be sure to perform the decrement in the same thread. On the contrary you will have race condition problems.
Second more clean way. Subclass AFHTTPClient
and use – enqueueBatchOfHTTPRequestOperationsWithRequests:progressBlock:completionBlock:
method. From AFNetworking doc.
Creates and enqueues an AFHTTPRequestOperation to the HTTP client’s operation queue for each specified request object into a batch. When each request operation finishes, the specified progress block is executed, until all of the request operations have finished, at which point the completion block also executes.
NSMutableArray *operations = [NSMutableArray array];
for (id element in elements) {
NSMutableURLRequest *request = // your request here
AFHTTPRequestOperation *operation = [[YourAFHTTPClientSubclass sharedClient] HTTPRequestOperationWithRequest:request success:^(AFHTTPRequestOperation *operation, id responseObject) {
//
// Handle success here
//
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//
// Handle error here
//
}];
//
// Add all operations to the operations NSArray
//
[operations addObject:operation];
}
//
// Pass off operations array to the sharedClient so that they are all executed
//
[[YourAFHTTPClientSubclass sharedClient] enqueueBatchOfHTTPRequestOperations:operations progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) {
NSLog(@"Completed %d of %d create operations", numberOfCompletedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
//
// All operations are completed
//
}];
Edit
In your first operation create an array of dict element like the following
NSMutableArray *elements = [NSMutableArray array];
for (int i = 1; i <= self.numOfWallPosts; i++)
{
NSString *sharedKey = [NSString stringWithFormat:@"wall_number_%d", i];
NSMutableDictionary *aaa = [[NSMutableDictionary alloc] init];
aaa = [self.sharedPrefs objectForKey:sharedKey];
[elements addObject:aaa];
}
[self handleWallPostsWithWallPost:elements];
Now, handleWallPostsWithWallPost:
will contain the code I provided.
elements
is an array of elements dictionary you pass to your method. The for
loop allows you to create the image operations.
Upvotes: 1