I am downloading a JSON feed asynchronously in my App Delegate class. Now the data is taking a while to load, so my table view appears empty at first, and then populates a few seconds after. Therefore, I would like to either:
1- Find out what is causing this delay. Therefore, keep all the activity in the application:didFinishLaunchingWithOptions method and only load the VC after everything has been loaded.
OR
2- Display an activity indicator until the table populates the data.
Now in the first scenario, I am pretty sure that I am pushing the view controller at the wrong time. I tried playing around with it but it seems that that is the only way my app will build and run.
In the second scenario, I would like to know which “connection” method gets invoked first, and which one last. Therefore, I will be able to start up the activity indicator view at the first method and release at the end of the last method.
Below is my code. Any suggestions/help is greatly appreciated. Thank you for reading.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[responseData setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
[responseData appendData:data];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
UIAlertView *alert = [[UIAlertView alloc]
initWithTitle:@"Error"
message:@"Please check your network connection and relaunch the application"
delegate:self
cancelButtonTitle:@"Dismiss"
otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
if ([responseString isEqualToString:@"Unable to find specified resource."]) {
NSLog(@"Unable to find specified resource.n");
}
else {
ListingsViewController *listingsViewController = [[ListingsViewController alloc] initWithNibName:@"ListingsViewController" bundle:nil];
listingsViewController.jsonData = responseString;
[self.navigationController pushViewController:listingsViewController animated:NO];
[self.navigationController setViewControllers:[NSArray arrayWithObject:listingsViewController] animated:NO];
[listingsViewController release];
}
[connection release];
[responseData release];
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Start the HTTP request
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:@"http://www.shoofeetv.com/iphonexml/view/all_channels.json"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
// Display the navigation controller
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
Go with option 2. It’s good UI design to display things as quickly as possible, even though the UI might not be useful until the data has loaded it will at least make users of your application feel like something is happening.
Pop the UI in didFinishLaunchingWithOptions, display an activity indicator and in connectionDidFinishLoading hide and destroy the activity indicator.
I would also recommend wrapping all the async http request logic in to another class, and have it accept a delegate, then for example you could call: