When to load data into a UITableViewController?

I am currently loading data from a JSON service into the viewDidLoad method in a UITableViewController . The problem is that data takes time to extract and analyze; presentation takes time to create. Where is the best place to download this data? I assume that somewhere there is a hook for loading data after creating the view. By doing this, I can use some UIActivityIndicatorView in the final view. Thanks

+7
source share
3 answers

Finally, this comment-based solution: Run the stream in viewDidLoad to get the data without blocking everything:

 - (void) viewDidLoad { dataLoaded = NO; [self initSpinner]; [self launchLoadData]; ... } -(void)launchLoadData { NSLog(@"Launching thread"); [NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil]; } - (void) loadData { dataLoaded = NO; NSLog(@" thread launched"); NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; [self loadDataFromURL:nil]; dataLoaded = YES; [self.tableView reloadData]; [pool release]; } - (void)loadDataFromURL:(NSString*)url { // start the spinner to show that loading may be time consuming... [NSThread detachNewThreadSelector: @selector(spinBegin) toTarget:self withObject:nil]; JSONLoader *loader = [[JSONLoader alloc] init]; self.accounts = [loader getAccountsFromURL:@"http://foo/bar/repository.json"]; [loader release]; //[NSThread sleepForTimeInterval:3]; [NSThread detachNewThreadSelector: @selector(spinEnd) toTarget:self withObject:nil]; } 

and use the flag to display or missing data in the table. tableView reloadData will do the rest when called from the stream.

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (dataLoaded) return [self.accounts count]; return 0; } 
+5
source

I think what you are trying to ask is the workflow for displaying data from a web service in a UITableView.

Here is what I recommend:

  • Your viewDidLoad creates an NSURLRequest for your JSON file. Also adds a loading view to the current view (I am using UIView with black bg (0.5 alpha), plus the label and identifier UIActivityIndicator). In this, you will also set BOOL ivar (which you need to add to your header), called loaded , to NO.

  • You are merging your NSURLRequest data because it comes down to a mutable data object.

  • When your NSURLRequest ends, you turn its data into a string, and parse the JSON into some sort of array (or a dictionary, if you want). In the same method, you delete the load view and change your logical loaded - YES. Then you indicate that tableView is reloading its data: [self.tableView reloadData];

Here where the magic happens ... in table view methods

 - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { if (loaded) return [myArrayOfJSONObjects count]; return 0; // Will only return 0 if the data is not downloaded } - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { NSUInteger row = [indexPath row]; static NSString *CellIdentifier = @"Cell"; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; if (cell == nil) { cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease]; } // Configure the cell... if (loaded) { cell.textLabel.text = [myArrayOfParsedJSONObjects objectAtIndex:row]; //Anything else you want to set } else { //Do nothing :) - you shouldn't reach this else anyway because your numberOfRows method should stop it } } 
+1
source

You can open a new view and show the UIActivityIndicator with a message to the user that you are loading fresh data for him.

For me, this is the best choice, because the interface remains responsible, and the user sees that you are actually doing something, and the application is not hung.

0
source

All Articles