NSURLConnection Reloading My View
So I am using NSURLConnection delegate to download a JSON feed in my AppDelegate.m file. Now I have a problem. My application:didFinishLaunchingWithOptions is shown below:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Display the progress indicator
HUD = [[MBProgressHUD showHUDAddedTo:self.navigationController.view animated:YES] retain];
// Start the HTTP request
responseData = [[NSMutableData data] retain];
NSURLRequest *request = [NSURLRequest requestWithURL:
[NSURL URLWithString:@"*****some url here*********"]];
[[NSURLConnection alloc] initWithRequest:request delegate:self];
// Display the navigation controller
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
So all I do is display an activity indicator, start the HTTP request (which is when the NSURLConnection delegate starts working) and then I display my Navigation Controller's root view controller. Now the problem is that it will load that view, which has a table view, without any data in it (since NSURLConnection) hasn't finished downloading the data. It looks quite ugly because I have static UILabels that I made on interface builder so it displays them and then after loading it will show the data. I have an activity indicator in the middle of the screen so all along the user knows that new data is loading.
Now after my NSURLConnection finishes downloading the data, the view loads one more time for some weird reason. I know that because if I put NSLog(@"Test"); in my viewDidLoad method, it prints out twice. At the end of the application:didFinishLaunchingWithOptions and at the end of the connectionDidFinishLoading. Why is that? How do I make it look neat, where the view loads once after my data has been loaded? Any suggestions?
Thank you all,
EDIT: More code in the AppDelegate before application:didFinishLaunchingWithOptions
- (void)hudWasHidden {
// Remov开发者_开发技巧e HUD from screen when the HUD was hidded
[HUD removeFromSuperview];
[HUD release];
}
#pragma mark -
#pragma mark NSURLConnectionDelegete
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(@"Starting Response");
[responseData setLength:0];
expectedLength = [response expectedContentLength];
currentLength = 0;
// Change the progress indicator to the loading wheel
HUD.mode = MBProgressHUDModeDeterminate;
NSLog(@"Done Response");
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"Starting Data");
[responseData appendData:data];
currentLength += [data length];
// Calculate progress indicator progress
HUD.progress = currentLength / (float)expectedLength;
NSLog(@"Done Data");
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"Start Error");
[HUD hide:YES];
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];
[connection release];
NSLog(@"Done Error");
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSLog(@"Start Finish Loading");
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];
}
// Save the pList to the Documents directory in iOS
ListingsViewController *listingsViewController = (ListingsViewController *)[self.navigationController topViewController];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectoryPath = [paths objectAtIndex:0];
NSString *plistFilePathInDocumentsDirectory = [documentsDirectoryPath stringByAppendingPathComponent:@"Channels.plist"];
// Instantiate a modifiable array and initialize it with the content of the plist file
NSMutableDictionary *channelsData = [[NSMutableDictionary alloc] initWithContentsOfFile:plistFilePathInDocumentsDirectory];
if (!channelsData) {
NSString *plistFilePathInMainBundle = [[NSBundle mainBundle] pathForResource:@"Channels" ofType:@"plist"];
// Instantiate a modifiable array and initialize it with the content of the plist file in main bundle
channelsData = [[NSMutableDictionary alloc] initWithContentsOfFile:plistFilePathInMainBundle];
}
// Set the ListingsViewController's's savedChannels array
listingsViewController.channelsDict = channelsData;
[channelsData release];
// Display progress indicator checkmark and hide
HUD.customView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"37x-Checkmark.png"]] autorelease];
HUD.mode = MBProgressHUDModeCustomView;
[HUD hide:YES afterDelay:1];
[connection release];
[responseData release];
NSLog(@"Done finish loading");
[window removeFromSuperview];
}
It's all in your code:
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];
You're creating a new ListingsViewController and replacing the old one with it. The new ListingsViewController doesn't have its view loaded yet. (You don't need to call both -pushViewController:animated:
and -setViewControllers:
; the second one overrides the first in this case).
Other things:
- In
-hudWasHidden
, you probably want to do[HUD release]; HUD = nil;
. - It's not clear what
[window removeFromSuperview]
is trying to achieve (it probably does nothing, since windows don't have superviews).
精彩评论