views:

127

answers:

1

So i'm working on an iphone app that parses json and tries to put the results into a plain UITableview. I have my tableview setup in the xib file and also setup the datasource and the delegate as the MainViewController (this is utility application). I get the JSON request just fine and I always test this by outputting it to a text label. But when I debug and hover over the cellData var (which holds this data), it shows out of scope, and my simulator shows an empty table that won't scroll...like it's stuck waiting for something to finish.

Here is my header for the view controller:

#import "FlipsideViewController.h"

@interface MainViewController : UIViewController <FlipsideViewControllerDelegate,     UITableViewDelegate, UITableViewDataSource> {
IBOutlet UILabel *label;
UITableView *theTableView;
NSMutableArray *cellData;

}
@property (nonatomic, retain) IBOutlet UILabel *label;
@property (retain) NSMutableArray *cellData;
- (IBAction)showInfo:(id)sender;

@end

and here is my implementation:

#import "MainViewController.h"
#import "JSON.h"


@implementation MainViewController
@synthesize label;
@synthesize cellData;
//Begin code for Table View Data Source (required methods)

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView 
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    //how many rows in the section; for testing purposes...placed here
    return [cellData count];
    //return 20;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //create a cell
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if(cell == nil)
    {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];     
    }

    //fill it with contents
    cell.textLabel.text = [cellData objectAtIndex:indexPath.row];
    //return it
    return cell;
}

//End code for Table View Data Source

//Begin code for JSON stuffs

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad 
{
    [super viewDidLoad];

    //TODO: need to extract this code out to a function because need to make multiple requests per run of the app....
    //responseData = [[NSMutableData data] retain];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:@"https://tabular.heroku.com/tab_stores/tester.json"]];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
    cellData = [[NSMutableArray alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{

    NSMutableData *mutData = [[NSMutableData alloc] init];
    [mutData appendData:data];

    NSString *responseString = [[NSString alloc] initWithData:mutData encoding:NSUTF8StringEncoding];

    NSArray *responseData = [responseString JSONValue];

    NSMutableString *text = [NSMutableString stringWithString:@"T:"];

    for (int i = 0; i < [responseData count]; i++)
        [text appendFormat:@"%@\n", [responseData objectAtIndex:i]];

    label.text =  text;

    NSLog(@"%@\n", cellData);
    //Let's parse the data the way its supposed to be

    //for every window, there should be a section.
    for (int i=0; i<[responseData count]; i++) {
        //manage table section
        //maybe print window 1

    }


    //[cellData addObject:[responseData objectAtIndex:0]];
    [cellData addObjectsFromArray:responseData];
//  [responseData release];
    NSLog(@"%@\n", cellData);


    [theTableView reloadData];

    [responseString release];
    [mutData release];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{
    label.text = [NSString stringWithFormat:@"Connection failed: %@", [error description]];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
    [connection release];

    //NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

    //[responseData release];

    //cellData = [responseString JSONValue];

    //NSLog(@"this is in tabs %@", tabs);
//  NSLog(@"this is in cellData %@", cellData);
//      NSLog(@"this is in cellDatas %@", cellDatas);

    //NSMutableString *text = [NSMutableString stringWithString:@"T:"];

//  for (int i = 0; i < [cellDatas count]; i++)
//      [text appendFormat:@"%@\n", [cellDatas objectAtIndex:i]];

//  label.text =  text;

    //[theTableView reloadData];
}


//End code for JSON stuffs

.
.
.

- (void)dealloc 
{
  [theTableView release];
//[cellData release];
  [super dealloc];
}

I know that the tableview calls those functions for number of sectionsiInTableView and numberOfRowsInSection first so it won't get the data, but then I thought calling reloadData would work...but nothing. Can anyone help a newbie out?

*NSLogs in console:

2010-08-15 15:42:07.421 Tabular[33046:207] (
)
2010-08-15 15:42:09.902 Tabular[33046:207] (
    (
            (
        Google,
        "https://www.google.com/"
    ),
            (
        "https://tabular.heroku.com/tab_stores/tester",
        "https://tabular.heroku.com/tab_stores/tester"
    ),
            (
        "test - Google Search",
        "http://www.google.com/search?client=safari&amp;rls=en&amp;q=test&amp;ie=UTF-8&amp;oe=UTF-8"
    ),
            (
        "Using POST method in XMLHTTPRequest(Ajax)",
        "http://www.openjs.com/articles/ajax_xmlhttp_using_post.php"
    ),
            (
        "json stringify - Google Search",
        "http://www.google.com/search?client=safari&amp;rls=en&amp;q=json stringify&ie=UTF-8&oe=UTF-8"
    ),
            (
        "json.stringify escape - Google Search",
        "http://www.google.com/search?q=json.stringify escape&hl=en&safe=off&client=safari&rls=en&ei=PUlaTNiYL4O78gbt8bXsAg&start=10&sa=N"
    )
),
    (
            (
        Google,
        "https://www.google.com/"
    )
)
)
+1  A: 
  • It looks like each item in cellData is itself another array. It's not an NSString, so assigning it to a text field's "text" is unlikely to work (I'm surprised it doesn't crash). When in doubt, call [obj description], which is supposed to return an NSString.
  • connection:didReceiveData: can be called multiple times per connection. Your commented-out code is on the right track (buffer all the data once and process everything in connectionDidFinishLoading:; alternatively, process it with a stream-based API if you have one; I don't think the JSON library you use supports that).
  • You curiously make a mutable copy of the data but then don't otherwise mutate it.
tc.
+1 looks right and complete to me.
tonklon