0

I have a parsed data from JSON file. It works like a charm in the first view of my UITableView. However, it displays a blank second view when I tap on an item.

MasterView.h

@interface MasterViewController : UITableViewController
{
    NSArray *json;
}

@property (nonatomic, retain) NSArray *json;

@end

MasterView.m

#import "MasterViewController.h"
#import "InformationViewController.h"

@interface MasterViewController ()

@end

@implementation MasterViewController

@synthesize json;

- (void)viewDidLoad
{
    [super viewDidLoad];

    NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://j4hm.t15.org/ios/console.php"]];
    [self performSelectorOnMainThread: @selector(fetchedData:) withObject: jsonData waitUntilDone: YES];
}

- (void)fetchedData:(NSData *)responseData
{
    NSError *error;

    self.json = [NSJSONSerialization JSONObjectWithData: responseData options: kNilOptions error: &error];

    NSLog(@"String is %@", self.json);
}

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

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

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
        cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
    }

    cell.textLabel.text = [[json objectAtIndex: indexPath.row] objectForKey: @"Console"];

    [cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];

    return cell;
}


- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    InformationViewController *informationViewController = [[InformationViewController alloc] initWithStyle:UITableViewStylePlain];

    informationViewController.title  = [[json objectAtIndex: indexPath.row] objectForKey: @"Console"];
    informationViewController.Information = [[json objectAtIndex: indexPath.row] objectForKey: @"Model"];

    NSLog(@"String is %@", informationViewController.Information);

    [self.navigationController pushViewController: informationViewController animated:YES];

}

InformationView.h

@interface InformationViewController : UITableViewController

@property (nonatomic, strong) NSArray * Information;

@end

InformationView.m

@interface InformationViewController ()

@end

@implementation InformationViewController

@synthesize Information;

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
    }

    // Configure the cell...

    cell.textLabel.text = [[Information objectAtIndex: indexPath.row] objectForKey: @"Model"];

    [cell setAccessoryType: UITableViewCellAccessoryDisclosureIndicator];

    return cell;
}
Jahm
  • 658
  • 1
  • 12
  • 27
  • first NSLog(@"%@",self.Information); and tell me what it prints ? – TheTiger Jan 05 '13 at 11:41
  • I have `NSLog(@"String is %@", informationViewController.Information);` in `didSelectRowAtIndexPath` and the result is `2013-01-06 01:03:19.641 JSON04[10867:c07] String is (null)` in my MasterView.m. Other than that, I also have `NSLog(@"viewDidLoad: %@", self.Information);` in `viewDidLoad` and the result is `2013-01-06 01:03:19.642 JSON04[10867:c07] viewDidLoad: (null)` in my InformationView.m. – Jahm Jan 05 '13 at 17:06
  • Download the Project Here :http://www.cogzentappz.com/demo/iostutorial/TestJson.zip – Siba Prasad Hota Jan 06 '13 at 21:08

3 Answers3

1

Here i Posted Another Answer Just Because i don't want to Generate Confusion.

The Project Code : http://www.cogzentappz.com/demo/iostutorial/TestJson.zip

instead of passing the Selected Value, Pass the Whole Array through NSUsedDefaults And Retrive them Using Following Code.

  - (void)fetchedData:(NSData *)responseData
    {
        NSError *error;

        self.json = [NSJSONSerialization JSONObjectWithData: responseData options: kNilOptions error: &error];

        NSLog(@"String is %@", self.json);

     NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
        NSMutableArray *arrayObj = [[NSMutableArray alloc] init];


        for(int i = 0 ; i<[self.json count] ; i++) {
            [arrayObj addObject:[json objectAtIndex:i]]];
        }

        [standardDefaults setObject:arrayObj forKey:@"longArray"];
        [arrayObj release];


    }

In the Next View you can Retrive the data Using the Below method. in ViewDidLoad of informationViewcontroller use This

//reading

NSUserDefaults *standardDefaults = [NSUserDefaults standardUserDefaults];
NSArray *arrayObj = [standardDefaults objectForKey:@"longArray"];


for(int i = 0 ; i<[arrayObj count] ; i++) {
        NSLog(@"String is %@",[arrayObj objectAtIndex:i]);
    }

As per Your Link The Json Output is like Below :

NSArray-->NSDictionary-->NSArray-->NSDictionary-->NSArray-->NSDictionary

Go to the link : http://json.bloople.net and Post all your json output and Hit enter.

So you have to get the values According to that format.

for(int i = 0 ; i<[self.json count] ; i++) {
 NSArray *info_Array=[[self.json objectAtIndex:i ]valueForKey:@"Information"];
    NSLog(@"info_Array is %@", info_Array);

    for(int j = 0 ; j<[info_Array count] ; j++)
    {

        NSLog(@"Model is %@", [[info_Array objectAtIndex:j ]valueForKey:@"Model"]);
        NSArray *title_Array=[[info_Array objectAtIndex:j ]valueForKey:@"Title"];
        for(int k = 0 ; k<[title_Array count] ; k++)
        {
            NSLog(@"Game is %@", [[title_Array objectAtIndex:k ]valueForKey:@"Game"]);
            NSLog(@"Publisher is %@", [[title_Array objectAtIndex:k ]valueForKey:@"Publisher"]);
        }

    }

    NSString *Console_string= [[dataArray objectAtIndex:i ]valueForKey:@"Console"];
    NSLog(@"String is %@", Console_string);

}

NSString *Console_string= [[self.Json objectAtIndex:i ]valueForKey:@"Console"];
NSLog(@"String is %@", Console_string);
}
Siba Prasad Hota
  • 4,779
  • 1
  • 20
  • 40
  • What is the code for, if I may ask. It has an exception: `2013-01-06 18:37:32.927 JSON04[14725:c07] *** Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFArray objectAtIndex:]: index (3) beyond bounds (3)' *** First throw call stack:` – Jahm Jan 06 '13 at 10:46
  • There is an improvement already. The `NSLog(@"String is %@",[arrayObj objectAtIndex:i]);` you added in `viewDidLoad` of my InformationView.m displays three different output. First is for PlayStation, `2013-01-06 19:06:28.335 JSON04[14944:c07] String is { Console = PlayStation; Information = (...); }`. Second is for Wii, `2013-01-06 19:06:28.336 JSON04[14944:c07] String is { Console = Wii; Information = (...); }`. And lastly is for Xbox, `2013-01-06 19:06:28.336 JSON04[14944:c07] String is { Console = Xbox; Information = (...); }` – Jahm Jan 06 '13 at 11:09
  • But if I am going to pass the data in the 3rd, 4th or up to 5th view, do I need to add the code in `viewDidLoad` and repeat the whole procedure? The UITableView looks like this, MasterView (Display what consoles: PlayStation, Xbox, Wii). InformationView (Display what models: PS3, PS2, PSX, Wii, Xbox, Xbox 360). I still have to add GameView (Display what are the games available for that model and who published it) – Jahm Jan 06 '13 at 13:57
  • By the way, that last code you added. Will I add it in the `viewDidLoad` of my InformationView? – Jahm Jan 06 '13 at 14:00
  • Okay! Roger that! Thank you! – Jahm Jan 06 '13 at 14:03
  • I'm so sorry to disappoint you, but I really can't display the results. :( – Jahm Jan 06 '13 at 15:30
  • Sir, may I know what is `NSUserDefaults` for? – Jahm Jan 07 '13 at 07:46
  • in NSUserDeafaults you can save the Value in One place and use that Anywhere. Also you can google it to find more. https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/NSUserDefaults_Class/Reference/Reference.html click on the link and get details from Apple developer website. You also can use Appdelegate to pass values. – Siba Prasad Hota Jan 07 '13 at 08:04
  • How do you display the Game and Publisher detail in the fourth view? – Jahm Jan 07 '13 at 09:40
  • i cant get you. What you want ? Want to display all games with publisher ? – Siba Prasad Hota Jan 07 '13 at 09:42
  • There are two Games with corresponding Publisher each Model of the Console. If for example I want to display the detail of `Ace Combat` of Model `PlayStation 1` of Console `PlayStation`. I want the detail (title of the game, and its publisher) to be displayed in a separate (fourth) view. – Jahm Jan 07 '13 at 09:59
  • can you draw a sketch of your 4th view ? Currently its showing Title and Publisher in 3rd View. Just pass these velues to 4th View. – Siba Prasad Hota Jan 07 '13 at 10:06
  • This will be the fourth and final view: http://cl.ly/image/2r11022d0M3D - Yes, that's the idea but it seems that I don't know how the process works. – Jahm Jan 07 '13 at 10:16
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/22308/discussion-between-siba-prasad-hota-and-jahm) – Siba Prasad Hota Jan 07 '13 at 11:09
0

Change your code of MaterView.m with this

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
InformationViewController *informationViewController = [[InformationViewController alloc] initWithStyle:UITableViewStylePlain];
informationViewController.title  = [[json objectAtIndex: indexPath.row] objectForKey: @"Console"];
informationViewController.Information = [[json objectAtIndex: indexPath.row] objectForKey: @"Model"];
NSLog(@"String is %@", informationViewController.Information);
[self.navigationController pushViewController: informationViewController animated:YES];
}

Hope it helps you...

Siba Prasad Hota
  • 4,779
  • 1
  • 20
  • 40
P.J
  • 6,547
  • 9
  • 44
  • 74
0

I think you have to reloadData after you fetch your data. Right now, you specify that the NSArrray *json is empty, since the count returns 0. Thus, you prohibit the table view from being filled. Call [tableView reloadData]; after you fetch your data.

ipinak
  • 5,739
  • 3
  • 23
  • 41
  • Does the NSLog inside the fetchData print anything? – ipinak Jan 05 '13 at 17:23
  • Yes it does. It prints the data is inside the link. – Jahm Jan 05 '13 at 17:26
  • Are you sure you get an NSArray and not a dictionary? – ipinak Jan 05 '13 at 17:29
  • Pretty sure because I just imported these data from an old project to make us of NSJSONSerialization. In my previous project, I was using NSArray, and not NSDictionary. Whenever I change the type of json to NSDictionary, I get an exception. – Jahm Jan 05 '13 at 17:31