2

I'm trying to parse a JSON from this URL, which is a JSON output from Wordpress. For some reason, there's no output in the UITableView.

Here's the code I have got to parse. I'm sure I'm missing out something but I'm not able to figure out how to parse Nested JSON in this code.

ViewController.m:

    - (void)viewDidLoad
{
    [super viewDidLoad];
    self.title = @"News";

    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

    NSURL *url = [NSURL URLWithString:@"http://www.karthikk.net/?json=1"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [[NSURLConnection alloc] initWithRequest:request delegate:self];
    // Do any additional setup after loading the view, typically from a nib.
}

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    data = [[NSMutableData alloc] init];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)theData
{
    [data appendData:theData];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    news = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
    [mainTableView reloadData];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    UIAlertView *errorView = [[UIAlertView alloc] initWithTitle:@"Error" message:@"The download could not complete - please make sure you're connected to either 3G or Wi-Fi." delegate:nil cancelButtonTitle:@"Dismiss" otherButtonTitles:nil];
    [errorView show];
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

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

- (int)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [news count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"MainCell"];

    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:@"MainCell"];
    }

    cell.textLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:@"title"];
    cell.detailTextLabel.text = [[news objectAtIndex:indexPath.row] objectForKey:@"date"];

    return cell;
}

ViewController.h

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController {
    IBOutlet UITableView *mainTableView;

    NSArray *news;
    NSMutableData *data;
}

@end

Please help me out in paring this.

Thanks much! I've tried referring to multiple threads on Stackoverflow, but all failed to work for me.

P.S.: I'm a newbie to iOS App Development. And I'm using this Video tutorial to mess with the code.

Karthik Kamalakannan
  • 770
  • 1
  • 11
  • 31
  • What if any errors are you getting? Without knowing what your header file looks like it's difficult to just copy/paste your code and see what's happening. – propstm Dec 21 '12 at 17:06
  • Do this: NSLog(@"news = %@", [news description]); right after you assign news to the JSON value And post the result (if the result is huge, post the first few objects) – LJ Wilson Dec 21 '12 at 17:06
  • I've updated the question with the header file. And @ElJay, How can I do that? Could you please help? – Karthik Kamalakannan Dec 21 '12 at 17:07

1 Answers1

4

I see what the problem is. The news object is a Dictionary that has several key value pairs and one of them is posts which actually contains the Array that you want to use to populate your TableView.

Here is the first little bit from your JSON response:

{"status":"ok","count":10,"count_total":662,"pages":67,"posts":[{"id":6176,"type":"post","slug":"how-to-save-any-photo-from-facebook-to-your-iphone-or-ipad-or-ipod-touch","url"...

When you see a { in a JSON response that indicates a Dictionary, a [ indicates an Array. TableViews are populated from an Array usually. So you can see that you have a JSON response of a Dictionary with several key-value pairs and one of those is an Array of Dictionary's

You need to assign the news object the contents of that Dictionary key:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    NSDictionary *responseDict = [NSJSONSerialization JSONObjectWithData:data options:nil error:nil];
    news = [responseDict objectForKey@"posts"];
    [mainTableView reloadData];
}
LJ Wilson
  • 14,445
  • 5
  • 38
  • 62
  • Brilliant. It worked just as I wanted it to work! Thanks much! Thanks a lot. – Karthik Kamalakannan Dec 21 '12 at 17:33
  • 1
    Anytime, this was a good question and the code you posted (along with that link) helped figure out the problem pretty quickly :) – LJ Wilson Dec 21 '12 at 17:34
  • Thanks again. Now figuring out to display images which are in the posts. – Karthik Kamalakannan Dec 21 '12 at 17:47
  • 1
    Look at my answer to this SO question: http://stackoverflow.com/questions/9786018/loading-an-image-into-uiimage-asynchronously I wrote a class just for this. – LJ Wilson Dec 21 '12 at 18:10
  • Another quick query: How do I access the inner array in the JSON. Like the thumbnail and author name? Could you please help me with that? @ElJay – Karthik Kamalakannan Dec 22 '12 at 05:08
  • The images object (dictionary) is actually what you need and the thumbnail object inside of that is another dictionary , you would just need to use something like NSDictionary *imagesDict = [[news objectAtIndex:indexPath.row] objectForKey:@"images"]; to create a dictionary and then something like: NSDictionary *thumbailDict = [images objectForKey:@"thumbnail"]; Then it is just a matter of doing : NSString *urlString = [thumbnailDict valueForKey@"url"]; To get author will be much of the same thing. – LJ Wilson Dec 22 '12 at 11:04