0

Lots has been written about this topic and I seem to be following exactly as the documentation indicates, but something is clearly a bit off. I'm thinking the issue is with the JSON.

Trying to take a JSON response, which looks like this:

JSON RESPONSE FROM NSLOG: 
{
  0 = "{\"name\":\"Dinner\", \"date\":\"2014-05-23\", \"time\":\"7:00PM\"}";
}

Convert it to an NSArray, like this:

NSString *url = @"http://localhost:8888/rendezvous/index.php/get_events";    
dispatch_async(kBgQueue, ^{
    NSURL *request=[NSURL URLWithString:url];
    NSData* data = [NSData dataWithContentsOfURL: request];
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSError* error;
        NSDictionary* json = [NSJSONSerialization
                         JSONObjectWithData:data
                         
                         options:kNilOptions
                         error:&error];
        
        _events = [[json valueForKey:@"0"] valueForKey:@"name"];

And output it to a tableViewCell like so:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    
    static NSString *CellIdentifier = @"EventCell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
    
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        cell.selectionStyle = UITableViewCellSelectionStyleNone;
    }
    
    cell.textLabel.text = [_events objectAtIndex:indexPath.row];
    
    return cell;
}

Presently, I'm getting null for the events array, presumably due to unfamiliarity on how to work with and access this bizarre-looking JSON response. How can I get on the right track here?

halfer
  • 19,824
  • 17
  • 99
  • 186
jeremytripp
  • 1,038
  • 1
  • 11
  • 25
  • If you get nil back from NSJSONSerialization then NSLog the `error` parm. If not, NSLog the `json` dictionary. Show us the results. (This is the sort of info that you should always include in your question.) – Hot Licks May 22 '14 at 20:40
  • And show us where you got `data` from. – Hot Licks May 22 '14 at 20:43
  • I just wrote a long answer on this for some joker who didn't even bother replying. It's very annoying when new users don't vote up answers, or just disappear. Possibly some of the code could help you here, cheers http://stackoverflow.com/a/23802660/294884 – Fattie May 22 '14 at 20:46
  • I just edited to add the bit about `data`. Also, I can confirm that the JSON response is being returned (I pulled the JSON above from the NSLog of the json dictionary). @Joe, I will check out your answer as soon as I submit this. – jeremytripp May 22 '14 at 20:55
  • And here is the error I receive upon running the code above: `Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x10135e80> valueForUndefinedKey:]: this class is not key value coding-compliant for the key name.` – jeremytripp May 22 '14 at 21:04
  • Your "JSON" is effed up and you can't really do anything until you fix it. Where did you get it?? – Hot Licks May 23 '14 at 00:09

1 Answers1

1

Your JSON is invalid...

0 = "{\"name\":Dinner, \"date\":\"2014-05-23\", \"time\":\"7:00PM\"}";

should be

{
    "0" : {
        "time" : "7:00PM",
        "name" : "dinner",
        "date" : "2014-05-23"
    }
}

Fix that, and your NSJSONSerialization call will work properly...

This code works:

NSString *inputJson = @"{\"0\":{\"time\":\"7:00PM\",\"name\":\"dinner\",\"date\":\"2014-05-23\"}}";

NSData * inputJsonData = [inputJson dataUsingEncoding:NSUTF8StringEncoding];

NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:inputJsonData
                                                         options:kNilOptions
                                                           error:nil];


NSDictionary * zeroDict = [jsonDict objectForKey:@"0"];
NSString * nameValue = [zeroDict objectForKey:@"name"];

Update:

I've also just noticed that you're trying to assign what is an NSString, into your _events array. That's not going to work, what you need to do is create a JSON array of events like this...

{
    "events" : [
        {
            "date" : "2014-05-23",
            "name" : "dinner",
            "time" : "7:00PM"
        },
        {
            "date" : "2014-05-26",
            "name" : "lunch",
            "time" : "12:00PM"
        }
    ]
}

Then you can pull out the events array in JSON...

_events = [jsonDict objectForKey:@"events"];

Then _events will be populated with an array of NSDictionary objects and in your table view method you can do the following...

NSDictionary * currentEvent = _events[indexPath.row];

cell.textLabel.text = [currentEvent valueForKey:@"name"];
Sammio2
  • 7,422
  • 7
  • 34
  • 49
  • Ok, fixed that issue. Thanks for the catch. Didn't change the outcome though. Still getting the same error as the comment above (class not key value coding compliant for the key name). – jeremytripp May 22 '14 at 21:18
  • Hmm, try pulling out the items seperately, e.g. `NSDictionary * dict = [json valueForKey:@"0"];` then `NSString * string = [dict valueForKey:@"name"];` – Sammio2 May 22 '14 at 21:21
  • Same story. Seems to be cool with `@"0"`, but doesn't like `@"name"` – jeremytripp May 22 '14 at 21:25
  • Sorry... Missed that one, your JSON is still invalid. It should look like this: `{"0":{"time":"7:00PM","name":"dinner","date":"2014-05-23"}}` – Sammio2 May 22 '14 at 21:26
  • Updated answer with full working code (minus the dispatch queue and error handling because i'm lazy!) – Sammio2 May 22 '14 at 21:32
  • Wow, ok, it looks like I've got some work to do. Thank you for your thorough responses. Once I manage to make all this magic happen, I'll mark it as the answer. Here's an upvote for your trouble! :) – jeremytripp May 22 '14 at 21:44
  • 1
    Because I'm in a really good mood... http://speedy.sh/FevP2/JsonTableViewSample.zip – Sammio2 May 22 '14 at 22:02
  • I'm guessing that the "0" is because whoever created the JSON tried to "index" a dictionary when constructing it, vs putting the inner value in an array. Obviously not the only screw-up. – Hot Licks May 23 '14 at 00:11
  • Jeremy - the secret then is this http://json.parser.online.fr Json has to be checked, "every single time". It's a pain in the ass. – Fattie May 23 '14 at 06:33
  • Or just use an industry standard JSON library to create your JSON, then it'll always be valid! – Sammio2 May 23 '14 at 06:35