0

I'm new to programming in general so please forgive my ignorance. If anyone can point me in the right direction it would be greatly appreciated.

I followed this tutorial for AFNetworking (http://www.raywenderlich.com/30445/afnetworking-crash-course) and have it working in my own project to parse JSON from the web.

I have yet to figure out how to transfer THAT data to a different UIViewController. I have seen Passing Data between View Controllers and other related questions to no avail.

I've tried using Delegates&Protocols/Singletons/GlobalVariables/ReferencingClasses and I can get them to work for other non JSON related material, when I NSLog the value it is always NULL. (Also the JSON data will be changing, and I read somewhere that some of these options are not mutable)

The tutorial seems to me to use custom NSDictionary classes to store the JSON Data and pass it over using prepareForSegue: but as far as I know, that is a Storyboard only method. I'm using nib files. Should I just switch my whole project to Storyboard style or is there a way to do this with Nibs/Xibs?

Thank you for taking the time to read this. The last thing I wanted to do is trouble you with a question but I've been stuck for a while now.

EDIT: I have retrieved JSON Data on the ViewController I preformed the request on, but it does not transfer over to other ViewControllers, and I feel it would be bad practice to request JSON data on every new Controller I need it on.

EDIT2 Here is some Code (I can post more if you want)

 

-(void)jsonData {

        NSLog(@"Loading JSON...");

        NSURL *url = [NSURL URLWithString:@"http://fillerCode.com"];

        AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];

        NSDictionary *params = [NSDictionary     dictionaryWithObjectsAndKeys:@"1",@"station",@"1",@"previous_song", nil];
    NSURLRequest *request = [httpClient requestWithMethod:@"POST" path:@"/scripts/MoreFillerCode" parameters:params];


    AFJSONRequestOperation *operation =
    [AFJSONRequestOperation JSONRequestOperationWithRequest: request

     // JSON SUCCESS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
NSLog(@"Getting Next Song...");

    self.get_next_song  = (NSDictionary *)JSON;

    RightViewController *rightViewController = [[RightViewController alloc] init];
    rightViewController.get_next_song = self.get_next_song;

    [self updateViewStuff];

} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
UIAlertView *av = [[UIAlertView alloc] initWithTitle:@"Error Retrieving Data"
                                             message:[NSString stringWithFormat:@"%@",error]
                                            delegate:nil
                                   cancelButtonTitle:@"OK"
                                   otherButtonTitles:nil];
[av show];
NSLog(@"Operation Failed");
}];

    [operation start];
    NSLog(@"JSON Operation Started");
}
Community
  • 1
  • 1
Rhotick
  • 177
  • 1
  • 1
  • 6
  • 1
    Are you sure you're the JSON response you're getting is valid/non-null? – Snowman Sep 16 '13 at 19:06
  • Yes the JSON response works on the ViewController I preform the AFJSONRequestOperation on, but nothing else. Sorry I didn't clarify that. I can have images, labels, and music all pulled from the web on that one ViewController. – Rhotick Sep 16 '13 at 19:21
  • It would help if you posted the relevant AFNetworking code. – Snowman Sep 16 '13 at 19:23
  • Sorry if the spacing is all weird. And is that enough? I can post more. – Rhotick Sep 16 '13 at 19:38
  • 1
    After the line `self.get_next_song = (NSDictionary *)JSON;`, add `assert(self.get_next_song);`, and run your app and see if it crashes. If it crashes on that line, it means your data is nil. If not, we'll have to investigate something else. – Snowman Sep 16 '13 at 19:43
  • 1
    Also, 1RightViewController *rightViewController1 doesn't seem to be used after that, and will get destroyed after the block exits. So whatever 1[self updateViewStuff]1 does, it will have nothing to do with that view controller. – Snowman Sep 16 '13 at 19:44
  • I don't know what assert() does (I'll have to research that) but it didn't crash my app. Is delegation the best way to do this? Maybe self.get_next_song is always deleted before the delegation reaches it because AFNetworking is done asynchronously? Also thank you very much for taking the time to help me with this. How do I upvote you? – Rhotick Sep 16 '13 at 19:54

2 Answers2

1

Your main problem:

I have retrieved JSON Data on the ViewController I preformed the request on, but it does not transfer over to other ViewControllers.

The reason for this problem:

RightViewController *rightViewController = [[RightViewController alloc] init];
rightViewController.get_next_song = self.get_next_song;

[self updateViewStuff];

You are allocating and instantiating a brand new view controller, and then setting a property on it. After this, you never mention rightViewController again, and it will be deallocated when the completion block ends. Any time you alloc-init, you're making a new one, and if you don't use it, set it to a @property, or push it on a navigation controller, it will simply disappear.

I don't know the rest of your app well enough to give you code to fix this, but here's a general idea for solving this type of problem:

  • Make a new class (NSObject, not UIViewController), that deals with sending / receiving data. Put all the AFNetworking stuff here.
  • When a view controller needs data, have it ask this new object for the data. The data should be given back to the view controller. The object can use saved data if it's available, or make a request using AFNetworking if it's not

This way, none of your view controllers need to know about each other - you don't need to pass data along a chain, you can just access it from your data source whenever you need it.

Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • Thank you very much for your time. I have a lot more to research to do. So I should put this code snippet in that NSObject rather than where it is right now and simply reference it from the UIViewControllers as they need the data? I'll see if that works. – Rhotick Sep 16 '13 at 20:09
  • Yes. That's just one approach, but generally speaking, downloading and parsing data does not belong in a view controller. A view controller should be told what data to display, and its only decisions should involve how the user sees & interacts with it. – Aaron Brager Sep 16 '13 at 20:17
0

If you want to make your example work, you need to make one of two following steps:

  1. Declare your RightViewController in @interface and refer to that declaration when initialize your object, set properties and then make segue.

  2. Make segue in the same block you're creating your RightViewController object - otherwise you loose reference to it.

ArturOlszak
  • 2,653
  • 2
  • 21
  • 20