简体   繁体   English

NSURLConnection重新加载我的视图

[英]NSURLConnection Reloading My View

So I am using NSURLConnection delegate to download a JSON feed in my AppDelegate.m file. 因此,我正在使用NSURLConnection委托在AppDelegate.m文件中下载JSON提要。 Now I have a problem. 现在我有一个问题。 My application:didFinishLaunchingWithOptions is shown below: 我的应用程序:didFinishLaunchingWithOptions如下所示:

- (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. 因此,我要做的就是显示一个活动指示器,启动HTTP请求(这是NSURLConnection委托开始工作的时间),然后显示导航控制器的根视图控制器。 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. 现在的问题是它将加载具有表视图的视图,其中没有任何数据(因为NSURLConnection)尚未完成数据的下载。 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. 它看起来很丑陋,因为我在接口构建器上制作了静态UILabel,因此它显示了它们,然后在加载后将显示数据。 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. 现在,在我的NSURLConnection完成下载数据之后,由于某种奇怪的原因,该视图又加载了一次。 I know that because if I put NSLog(@"Test"); 我知道,因为如果我把NSLog(@“ Test”); in my viewDidLoad method, it prints out twice. 在我的viewDidLoad方法中,它打印了两次。 At the end of the application:didFinishLaunchingWithOptions and at the end of the connectionDidFinishLoading. 在应用程序的末尾:didFinishLaunchingWithOptions以及在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 编辑:在应用程序之前,AppDelegate中有更多代码:didFinishLaunchingWithOptions

- (void)hudWasHidden {
    // Remove 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. 您正在创建一个新的ListingsViewController并将其替换为旧的。 The new ListingsViewController doesn't have its view loaded yet. 新的ListingsViewController尚未加载其视图。 (You don't need to call both -pushViewController:animated: and -setViewControllers: ; the second one overrides the first in this case). (您无需同时调用-pushViewController:animated:-setViewControllers:在这种情况下,第二个将覆盖第一个)。

Other things: 其他事情:

  • In -hudWasHidden , you probably want to do [HUD release]; HUD = nil; -hudWasHidden ,您可能想执行[HUD release]; HUD = nil; [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). 目前尚不清楚[window removeFromSuperview]试图实现什么(它可能什么也不做,因为Windows没有超级视图)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM