I'm developing an iPhone app that features a tab-bar based navigation with five tabs. Each tab contains a UITableView whose data is retrieved remotely. Ideally, I would like to use a single UIActivityIndicatorView (a subview of the window) that is started/stopped during this remote retrieval - once per tab.
Here's how I set up the spinner in the AppDelegate:
- (void)applicationDidFinishLaunching:(UIApplication *)application {
[window addSubview:rootController.view];
activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
[activityIndicator setCenter:CGPointMake(160, 200)];
[window addSubview:activityIndicator];
[window makeKeyAndVisible];
}
Since my tabs were all performing a similiar function, I created a base class that all of my tabs' ViewControllers inherit from. Here is the method I'm using to do the remote retrieval:
- (void)parseXMLFileAtURL:(NSString *)URL {
NSAutoreleasePool *apool = [[NSAutoreleasePool alloc] init];
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSLog(@"parseXMLFileAtURL started.");
[appDelegate.activityIndicator startAnimating];
NSLog(@"appDelegate.activityIndicator: %@", appDelegate.activityIndicator);
articles = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL URLWithString:URL];
rssParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[rssParser setDelegate:self];
[rssParser setShouldProcessNamespaces:NO];
[rssParser setShouldReportNamespacePrefixes:NO];
[rssParser setShouldResolveExternalEntities:NO];
[rssParser parse];
NSLog(@"parseXMLFileAtURL finished.");
[appDelegate.activityIndicator stopAnimating];
[apool release];
}
This method is being called by each view controller as follows:
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([articles count] == 0) {
NSString *path = @"http://www.myproject.com/rss1.xml";
[self performSelectorInBackground:@selector(parseXMLFileAtURL:) withObject:path];
}
}
This works great while the application loads the first tab's content. I'm presented with the empty table and the spinner. As soon as the content loads, the spinner goes away.
Strangely, when I click the second tab, the NSLog messages from the -parseXMLFileAtURL: method show up in the log, but the screen hangs on the first tab's view and I do not see the spinner. As soon as the content is done downloading, the second tab's view appears.
I suspect this has something to do with threading, with which I'm still becoming acquainted. Am I doing something obviously wrong here?