I am downloading data from different links using ASIHTTPRequest and NSOperationQueue to
download in background thread. When a request has finished i parse in using requestFinished
delegate method of ASIHTTPRequest. I want to update the data in tableview when all requests in
the queue has completed. Is there any way to know when an NSOperationQueue has processed all
requests? i mean queue has any variable like 'isEmpty' or any delegate method like 'queueDidCompletedAllOperation'?
please help.
Here is the code:
//source
@interface SourceModel : NSObject
@property (nonatomic, retain) NSString * link;
@property (nonatomic, retain) NSString * name;
@end
//for rssGroup
@interface CompleteRSSDataModel : NSObject
@property (nonatomic,strong) SourceModel * source;
@property (nonatomic,strong) KissXMLParser * parser;
@property (nonatomic,strong) NSArray * rssArticles;
@end
- (void)viewDidLoad
{
for (int index=0; index<[rssGroups count]; index++) {
NSString * urlString = [[[rssGroups objectAtIndex:index] source] link];
NSURL *url = [NSURL URLWithString:urlString];
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url]; [request setDelegate:self];
//set this request's tag to group index of this source(link). See requestFinished for use of this :)
[request setTag:index];
[self.queue addOperation:request];
}
}
- (void)requestFinished:(ASIHTTPRequest *)request {
NSLog(@"%@",@"RSS Data got from internet successfully :))");
int groupIndex = [request tag];
CompleteRSSDataModel * group = [rssGroups objectAtIndex:groupIndex];
group.parser = [[KissXMLParser alloc]initWithData:[request responseData]];
if (group.parser == nil) {
NSLog(@"%@",@"Failed - Error in parsing data :((");
}
else {
NSLog(@"%@",@"Data Parsed successfully :))");
group.rssArticles = [group.parser itemsInRss];
//So i want to check here that queue is empty, reload data, but as my information, i don't know any method like hasCompletedAllRequested
//if(self.queue hasCompletedAllRequests) {
// [self.tableview reloadData];
//}
}
}
- (void)requestFailed:(ASIHTTPRequest *)request {
NSLog(@"%@",@"Error in Getting RSS Data from internet:((");
}
If all operation has been completed then the operations
array count will be zero.
To check this you can use Key Value Observation Coding to observer the operations
key of NSOperationQueue
To set the observer for the key opertions
will be like below:
[self.queue addObserver:self forKeyPath:@"operations" options:0 context:NULL];
Then do this in your observeValueForKeyPath like below:
- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (object == self.queue && [keyPath isEqualToString:@"operations"]) {
if ([self.queue.operations count] == 0) {
// Do something here when all operations has completed
NSLog(@"queue has completed");
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
}
After iOS 4.0 you can use the property operationCount
like self.queue.operationCount == 0
instead of checking like this [self.queue.operations count] == 0