Sam Cromer
Sam Cromer

Reputation: 707

JSON and iOS 7 error

I have a JSON response that looks like this:

{"load_count":171,"play_count":142,"play_rate":0.9292035398230089,"hours_watched":2.795013611111111,"engagement":0.708595,"visitors":113}

When I try to set variables to the values here:

- (id)initWithJSONDictionary:(NSDictionary *)jsonDictionary {
if(self = [self init]) {
    // Assign all properties with keyed values from the dictionary
    _plays = [jsonDictionary objectForKey:@"load_count"];
    _hoursWatched = [jsonDictionary objectForKey:@"hours_watched"];
    _engagement = [jsonDictionary objectForKey:@"engagement"];

}

return self;

}

I get this error:

2014-02-04 11:16:37.180 BluGiant2[21192:1303] -[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x10a1176d0
2014-02-04 11:16:37.181 BluGiant2[21192:1303] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFString objectForKey:]: unrecognized selector sent to instance 0x10a1176d0'

so it's basically telling me it can't find "load_count" even though it's there. Is the issue that it's not an object since there are no [] around the JSON?

This is only the second attempt at loading JSON for me and the other one works, the only difference I see is the missing [].

Here is where I call it:

 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString: [NSString stringWithFormat:@"https://%s:%[email protected]/v1/stats/medias/c3e4797d8f.json", "api", "1b75e458de33a9b3f99d33f6bf409a7e145c570a"]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

[request setURL:url];
[request setHTTPMethod:@"GET"];
[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

NSError *error;
NSURLResponse *response;
NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

    NSMutableArray *videoDetail = [[NSMutableArray alloc] init];

    // Get an array of dictionaries with the key "locations"
    NSArray *array = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
    // Iterate through the array of dictionaries
    for(NSDictionary *dict in array) {
        // Create a new Location object for each one and initialise it with information in the dictionary
        VideoDetail *videoD = [[VideoDetail alloc] initWithJSONDictionary:dict];
        // Add the Location object to the array
        [videoDetail addObject:videoD];

        _textPlays.text = [NSNumberFormatter localizedStringFromNumber:videoD.plays numberStyle:NSNumberFormatterNoStyle];

    }


}

Upvotes: 0

Views: 326

Answers (2)

gnasher729
gnasher729

Reputation: 52612

Let's clarify that: The JSON that you posted is text containing a dictionary. JSON documents consist either of exactly one dictionary, or exactly one array.

If you passed the JSON that you posted to JSONObjectWithData, then you will get an NSDictionary*. Doesn't matter that you store it in an NSArray*; the compiler doesn't know what it gets so it allows the assignment, but you still have an NSDictionary.

The for loop is fun: for (... in ... ) takes arrays, dictionaries, sets, and iterates through the values in the array, dictionary or set. So you thought you iterate through an array, but you really iterate through the values in the dictionary, which are all strings. As before, the fact that you wrote for (NSDictionary* dict ...) doesn't matter, dict will always be an NSString.

And that leads to exactly the error that you got: You sent an objectForKey method to an NSString, which of course has no way to deal with that, and throws an exception.

Upvotes: 0

Gavin
Gavin

Reputation: 8200

The error message you're getting is letting you know that your JSON is stored as a string, not as an NSDictionary. What you need to do is convert your JSON.

Since your JSON is a string, get an NSData object first:

NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];

Then turn it into an NSDictionary using the NSJSONSerialization class:

NSError* error = nil;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

At that point, you will have an NSDictionary that you can work with.

EDIT:

It looks like you're trying to treat your JSON response as an array of dictionaries, but based on the JSON response you pasted above you actually just have a dictionary. So don't iterate over it, because I believe that's why you're encountering your issue. It's just iterating over the keys, which are strings.

Upvotes: 2

Related Questions