2

I am having a bit of trouble accessing the JSON data that I have pulled in. I am using the JSONModel to get my JSON data, like this:

At the Top of my LeftViewController.m

@interface LeftViewController ()
{
    PostgresFeed* _feed;
}

And then down below:

-(void)viewDidAppear:(BOOL)animated
{

JSONHTTPClient getJSONFromURLWithString:@"myurl" completion:^(NSDictionary *json,  JSONModelError *err) {
NSError *error = nil;

       _feed = [[PostgresFeed alloc] initWithDictionary:json error:&error];

       NSLog(@"Players: %@", feed.player);

       [self.tableView reloadData];

    }];
}

-(void)fetchedData:(NSData *)responseData
{
     NSError* error;
     NSDictionary* playerData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];

     NSMutableDictionary* player = [playerData objectForKey:@"player"];
}

- (id)initWithCoder:(NSCoder *)aDecoder
{
    if (self = [super initWithCoder:aDecoder])
    {
        _feed.player = [NSMutableArray array];
    }
return self;
}

And in my PostgresFeed.h

@property (nonatomic, strong) NSString *playerName;
@property (nonatomic, strong) NSString *currentScore;
@property (nonatomic, strong) NSArray *totalPenalties;
@property (nonatomic, strong) NSString *timePlayed;

And nothing in my PostgresFeed.m

I know that when I do it this way, I am getting all of the data that I want into my LeftViewController, which is the tableView of a MasterDetail. And when I look at the NSLog(@"Players: %@", feed.player); I can tell that I am getting all of the data that I want from the database.

How do I access this data that I know I have to populate my DetailViewController? Should I use NSUserDefaults? Should I create a new class to fetch, parse and hold onto this data?

I am new to this all, so a point to a tutorial, or tutorial like instructions are greatly appreciated. If any more code or details are needed, please let me know.

****EDIT****

After applying the NSNotificationCenter as suggested by @soryngod, I get the following output from my NSLog(@"%@", notification.userinfo); in my RightViewController:

    2013-07-04 12:20:26.208 PlayerTracking[25777:11303] {
    player =     (
                {
            currentScore = "4";
            totalPenalties =             (
            );
            id = 9;
            name = "Jakob Melon";
            timeStarted = "2013-06-05 19:56:10";
        },
                {
            currentScore = 16;
            totalPenalties =             (
            );
            id = 10;
            name = "John China";
            timeStarted = "2013-06-06 17:21:300";
        },
                {
            currentScore = 178;
            totalPenalties =             (
            );
            id = 11;
            name = "Jason Dog";
            timeStarted = "2013-06-07 19:26:10";
        },
                {
            currentScore = 1233;
            totalPenalties =             (
            );
            id = 12;
            name = "Fox Wolfe";
            timeStarted = "2013-06-05 19:56:10";
        },
                {
            currentScore = 234;
            totalPenalties =             (
            );
            id = 13;
            name = "Dakota Cool";
            timeStarted = "2013-06-05 19:56:10";
        },
                {
            currentScore = "34234";
            totalPenalties =             (
            );
            id = 14;
            name = "Max Face";
            timeStarted = "2013-06-05 19:00:30";
        },
                {
            currentScore = "2342";
            totalPenalties =             (
            );
            id = 15;
            name = "Jonatan Blah";
            timeStarted = "2013-06-05 18:00:30";
        },
                {
            currentScore = "234234";
            totalPenalties =             (
            );
            id = 16;
            name = "Thomas Bus";
            timeStarted = "2013-06-05 19:56:10";
        },
                {
            currentScore = 34566;
            totalPenalties =             (
            );
            id = 17;
            name = "Super Cake";
            timeStarted = "2013-06-05 17:51:30";
        },
                {
            currentScore = "23463";
            totalPenalties =             (
            );
            id = 18;
            name = "Duke Nukem";
            timeStarted = "2013-06-07 19:26:10";
        },
                {
            currentScore = "12362";
            totalPenalties =             (
            );
            id = 19;
            name = "Gordon Freeman";
            timeStarted = "2013-06-05 19:56:10";
        }
    );
}

Please, don't mind the names.

CaptJak
  • 3,592
  • 1
  • 29
  • 50
  • I think you can create an object to hold these data. To make it more flexible, you can make it as a singleton. – yibuyiqu Jul 04 '13 at 03:28

1 Answers1

2

You could use [NSNotificationCenter defaultCenter] to post the userInfo to the DetailController , when the data is received you just post a notification to with the feed and you handle it on the DetailController.

To be more explicit:

you add this to your DetailViewController viewDidLoad:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleNotification:) name:@"myNotification" object:nil];

then you create the method:

- (void) handleNotification:(NSNotification *) notification
{//Your information
NSLog(@"%@",notification.userInfo);
}

and from where you receive the JSON you post like this:

[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:nil userInfo:yourDictionary];

Let me know if this helps.

soryngod
  • 1,827
  • 1
  • 14
  • 13
  • I looked through that option, but I don't think this will work. What happens when I am dealing with 60+ entries? How would this work with my `didSelectRowAtIndexPath`? And what about when I have 6 fields to populate in my DetailView? Forgive me if this can be done and I am just being naive for asking these questions, but a more detailed answer would be very useful. – CaptJak Jul 04 '13 at 14:08
  • I think you should try it out. – soryngod Jul 04 '13 at 14:10
  • Please hold, givin' it a shot... – CaptJak Jul 04 '13 at 14:12
  • you can create an NSMutableDictionary and customize it for your needs. – soryngod Jul 04 '13 at 14:13
  • Well, I guess you could be right! I get all of my JSON data from the `NSLog(@"%@", notification.userInfo);`. I feel like a dunce for asking, but how would I get this new data to display in my UILabels and such? – CaptJak Jul 04 '13 at 14:23
  • The userInfo is a `NSDictionary`, so you get the values from that and assign them to your `UILabels` that I guess you have referenced from the `IBOutlet` . Or if you create those dynamically you can pass the `NSDictionary` as parameter to the function that instantiate the labels.I guess you know how to get the values : using `NSDictionary *dict = notification.userInfo; NSString *name = [dict objectForKey:@"playerName"];` and then you set the `nameLabel.text = name;` – soryngod Jul 04 '13 at 14:27
  • So I did as you said: `NSDictionary *playerData = notification.userInfo;` and then `NSString *name = [playerData objectforKey:@"name"];` and then nameLabel.text = name;` I get no errors, but nothing shows in my label, does this have something to do with the `DidSelectRowAtIndexPath`? I am currently fetching data for 20 players. – CaptJak Jul 04 '13 at 15:19
  • Maybe you have an array there instead of 1 NSDictionary so you should iterate thru them and select the one you need. Post the content of the notification.userInfo so i can know what to instruct you. – soryngod Jul 04 '13 at 16:13
  • Done. Check the OP. It's an NSDictionary, I'm sure. I get all data into my table view fine, so I know that my JSON is laid out according to my code. – CaptJak Jul 04 '13 at 16:34
  • Okay, Here is how you do : `NSArray *playerData = [notification.userInfo objectForKey:@"player"];` then you write `NSDictionary *firstElement = [playerData objectAtIndex:0];` and instantiate `nameLabel.text = [firstElement objectForKey:@"name"];` . Make sure nameLabel is linked in the IBOutlet. – soryngod Jul 04 '13 at 16:36
  • Marking this as the answer does not begin to convey my gratitude for your dedicated hard work and care in my difficulties... if you don't mind sticking around, the name is now static. How to I configure this to the `DidSelectRowAtIndexPath` so that it will change when I select another player in my MasterView? – CaptJak Jul 04 '13 at 16:42
  • So if you have 20 players in the MasterViewController you can do the same as here but instead of sending the FULL feed you send as parameter this : `NSArray *playerData = [yourJsonDict objectForKey:@"player"];` and you send as a parameter of this `[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:nil userInfo:[playerData objectAtIndex:indexPath.row]];` and on the other side you say directly : `NSDictionary *dict = notification.userInfo;` and set the `nameLabel.text = [dict objectForKey:@"name"];`. I'll leave for now , let me know if it worked. – soryngod Jul 04 '13 at 16:48
  • Um, I think I did something wrong or left something out. "Use of undeclared identifier `indexpath`". Should I declare `indexpath` as a global variable? where should I do this? – CaptJak Jul 04 '13 at 17:21
  • All right. I declared indexPath.row as a global variable, and now it only passes the first entry to the RightViewController, which was expected since `[[NSNotificationCenter defaultCenter] postNotificationName:@"myNotification" object:nil userInfo:[playerData objectAtIndex:indexPath.row]];` is only passing `objectAtIndex:indexPath.row` but it doesn't change when I click the names. I have a feeling I stuck this in the wrong method. Right now my JSON fetcher and NotificationCenter are in the viewDidAppear method of my MasterViewController. Should they be somwhere else? – CaptJak Jul 04 '13 at 18:37
  • Please explain exactly what you want to do. – soryngod Jul 04 '13 at 21:31
  • What I want to do is show a list of players in the master view (which I am doing), and show details about their games in the Detail view. At the bottom of the detail view is a small UIView which contains several labels that post recent stats. I have the data all filled in there, but the name and stats do not change when I select a different player. I have my `didSelectRowAtIndexPath` setup, but it doesn't seem to be doing anything (I followed the Ray Wenderlich tutorial on setting up a MasterDetail view). If you want, I can start a new question for this so I can post code and whatnot. – CaptJak Jul 04 '13 at 21:41
  • Is your Master view an uitableview? – soryngod Jul 04 '13 at 21:54
  • Yes it is, I used the MasterDetail UIViewController – CaptJak Jul 04 '13 at 22:00
  • Okay, so i understood that you have an uitableview in the left and that represents a list of player. You want that clicking on the name of the player (the tableview cell) to load in the DetailViewController the details of that player. Am I correct so far? – soryngod Jul 04 '13 at 22:03
  • spot on, and from earlier discussions on this question, you should also know that the data is all being gotten from a Postgres DB. I have been able to display the names from the DB in the table view and with your help, I have been able to pass the data from the MasterView to the DetailView. – CaptJak Jul 04 '13 at 22:06
  • Okay, so basically you can use the same list from the JSON to load in the Master uitableview and the other details are needed in the DetailViewController. If in the Master is "Fox Wolfe" in the Detail you want to show : "currentScore = 330000" , correct ? – soryngod Jul 04 '13 at 22:12
  • Yes, I want to show "Fox Wolfe, Current Score = 330000, total penalties = 0" and then when I select someone else, like "Super Cake" I want it to show "Super Cake, Current Score = 34566, totalPenalties = 0". Right now, I have a static "Jakob Melon" and stats showing in the Detail view, and selecting another player does nothing. – CaptJak Jul 04 '13 at 22:17
  • this is easy to do ,but we should talk on a chat because are many things to explain in order to get it right. – soryngod Jul 04 '13 at 22:26
  • I agree, but with only 3 rep points, I can not post on chat... unless you have some way of getting me up to 20 instantly... – CaptJak Jul 04 '13 at 22:27
  • The main idea is that you need to have the datasource of the uitableview the NSArray containing all the players , and you can set the cell.textLabel.text with the value of that certain indexPath.row from the NSArray which is an NSDictionary from where you get the objectForKey:@"name" all of this in the cellForRow delegate function of the uitableview. then in the didSelectRowAtIndexPath: delegate function you get the NSDictionary *dict = [jsonArray objectAtIndex:indexPath.row]; and you send this dict as I shown you with the NSNotification userInfo to the DetailViewController. – soryngod Jul 04 '13 at 22:36
  • All right that doesn't work, I create the NSDictionary in my ViewDidAppear function and then try to call it in the didSelectRowAtIndexPath, so that doesn't make sense. I am asking a new question called "didSelectRowAtIndexPath not working with NSNotificationCenter" So I can post code and stuff. This comment section is now longer than the Q&A section. If you want, you can find me there. Thank you for your help thus far, you have solved one of my problems! – CaptJak Jul 05 '13 at 00:24