Rich Carlton Rich Carlton - 3 months ago 9
Objective-C Question

Populating UITableView with an array

I am creating a array. The array is data from a website. I have to strip some stuff from it and process it (basically company info that I strip down to just one of each state).

The

allStatesFinalArray
is the array I want to show up on the table view. I can log it just fine in the fetchedData statement. But cannot get it into a tableview. I get several null response in the log from the table view log. Why? I know I am missing something. Please help.

//
// StateTableViewController.m
//

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) //1
#define kLatestKivaLoansURL [NSURL URLWithString:@"http://www.sensored.com"] //2

#import "StateTableViewController.h"
#import "ResViewController.h"

@interface StateTableViewController()
@end


@implementation StateTableViewController

- (void)viewDidLoad
{
[super viewDidLoad];

dispatch_async(kBgQueue, ^{
NSData *data = [NSData dataWithContentsOfURL:kLatestKivaLoansURL];
[self performSelectorOnMainThread:@selector(fetchedData:) withObject:data waitUntilDone:YES];
});

}

////new code???
NSArray *allStatesFinalArray;

- (NSArray *)fetchedData:(NSData *)responseData
{
//parse out the json data
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

NSArray *getCompaniesArray = [json objectForKey:@"CompaniesCD"]; //2 get all company info
NSArray *getStatesArray = [getCompaniesArray valueForKey:@"state"];//get only states
NSSet *getOneStateSet = [NSSet setWithArray:getStatesArray];//get rid of duplicates
NSArray* allStatesFinalArray= [getOneStateSet allObjects];//nsset to array

NSLog(@"allstatesfinalarray log 1 : %@", allStatesFinalArray);//return allStatesFinalArray;

return allStatesFinalArray;// return an array of just one state

}
////end newcode???


#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
//return 0;

NSLog(@"allstatesfinalarray log 2 : %@", allStatesFinalArray);//return allStatesFinalArray;

return [allStatesFinalArray count];
}
////NOTE ABOVE LOG RETURNS CORRECTLY!!!!

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
//get log after this step of the array
NSLog(@"here is the list going to tableview: %@", allStatesFinalArray);

static NSString *CellIdentifier = @"stateCell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

cell.textLabel.text = [allStatesFinalArray objectAtIndex:indexPath.row];

return cell;
}
//////NOTE ABOVE LOG RETURNS SEVERAL NILLS????????

- (IBAction)done:(id)sender {
[self dismissViewControllerAnimated:YES completion:nil];
}

@end

Answer

Your code is a confused mess. You have a variable declared between 2 methods:

////new code???
NSArray* allStatesFinalArray;

That makes it an application global variable, which is bad.

You have 2 variables called allStatesFinalArray; an application global, which should be an instance variable, and a local variable inside fetchData that should not exist at all.

Move that variable declaration to the header for your view controller class:

@interface StateTableViewController()
{
  NSArray* allStatesFinalArray;
}
@end

That makes it an instance variable.

Now change the fetchData method to not return a result:

- (void)fetchedData:(NSData *)responseData

Also, get rid of the decoration of a local variable allStatesFinalArray inside fetchData. Have the fetchData method save it's results into the allStatesFinalArray instance variable.

Now, as the last line of your fetchData method, call your table view's reloadData method.