How to get data from JSON?

I get the response back in JSON format and never parsed it in the past, so someone can help me figure this out. Here is the Json answer I get:

Twitter answer:

( { contributors = "<null>"; coordinates = "<null>"; "created_at" = "Tue Nov 29 15:48:35 +0000 2011"; entities = { hashtags = ( ); media = ( { "display_url" = "pic.twitter.com/650E1WRY"; "expanded_url" = "http://twitter.com/ashu1702/status/141544088850796545/photo/1"; id = 141544088854990848; "id_str" = 141544088854990848; indices = ( 22, 42 ); "media_url" = "http://p.twimg.com/AfbdmVBCEAAPJvT.jpg"; "media_url_https" = "https://p.twimg.com/AfbdmVBCEAAPJvT.jpg"; sizes = { large = { h = 279; resize = fit; w = 215; }; medium = { h = 279; resize = fit; w = 215; }; small = { h = 279; resize = fit; w = 215; }; thumb = { h = 150; resize = crop; w = 150; }; }; type = photo; url = "http://t.co/650E1WRY"; } ); urls = ( ); "user_mentions" = ( ); }; favorited = 0; geo = "<null>"; id = 141544088850796545; "id_str" = 141544088850796545; "in_reply_to_screen_name" = "<null>"; "in_reply_to_status_id" = "<null>"; "in_reply_to_status_id_str" = "<null>"; "in_reply_to_user_id" = "<null>"; "in_reply_to_user_id_str" = "<null>"; place = "<null>"; "possibly_sensitive" = 0; "retweet_count" = 0; retweeted = 0; source = "<a href=\"http://www.apple.com\" rel=\"nofollow\">iOS</a>"; text = "I am in Syria @(null) http://t.co/650E1WRY"; truncated = 0; user = { "contributors_enabled" = 0; "created_at" = "Sun May 01 15:20:52 +0000 2011"; "default_profile" = 1; "default_profile_image" = 1; description = "<null>"; "favourites_count" = 0; "follow_request_sent" = "<null>"; "followers_count" = 0; following = "<null>"; "friends_count" = 5; "geo_enabled" = 0; id = 291164338; "id_str" = 291164338; "is_translator" = 0; lang = en; "listed_count" = 0; location = "<null>"; name = "Ashutosh Tiwari"; notifications = "<null>"; "profile_background_color" = C0DEED; "profile_background_image_url" = "http://a0.twimg.com/images/themes/theme1/bg.png"; "profile_background_image_url_https" = "https://si0.twimg.com/images/themes/theme1/bg.png"; "profile_background_tile" = 0; "profile_image_url" = "http://a2.twimg.com/sticky/default_profile_images/default_profile_3_normal.png"; "profile_image_url_https" = "https://si0.twimg.com/sticky/default_profile_images/default_profile_3_normal.png"; "profile_link_color" = 0084B4; "profile_sidebar_border_color" = C0DEED; "profile_sidebar_fill_color" = DDEEF6; "profile_text_color" = 333333; "profile_use_background_image" = 1; protected = 0; "screen_name" = ashu1702; "show_all_inline_media" = 0; "statuses_count" = 62; "time_zone" = "<null>"; url = "<null>"; "utc_offset" = "<null>"; verified = 0; }; } ) 

In particular, I just need to expand_url, and I do this in my code to get it:

 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:responseData options:0 error:&error];// where response data is coming from the call made to twitter timeline_api NSString * callBackURL = [dict objectForKey:@"expanded_url"]; 

In doing so, I get this error:

 2011-11-29 09:50:31.214 L'Occitane[1119:19d07] -[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x85a50d0 2011-11-29 09:50:31.215 L'Occitane[1119:19d07] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x85a50d0' 

Help PLease !!!

Thanks,

+4
source share
1 answer

When converted to Cocoa Foundation objects, JSON splits into a bunch of nested NSArrays and NSDictionary , eventually leading to NSString s, NSNumber and NSNull s. Ideally, you will work forward from the web service documentation, but you can work backwards from the description that the root object prints through NSLog .

From your log, I see that expanded_url is a member of an unnamed object, which is the first entry in the media array, which is a member of the entities object. An unnamed object containing entities is part of the array, which will return the JSON deserializer. Therefore, you want to do something like (if written out in a long form for presentation and without any verification):

 NSArray *result = [NSJSONSerialization ... NSDictionary *firstObject = [result objectAtIndex:0]; NSDictionary *entities = [firstObject objectForKey:@"entities"]; NSArray *media = [entities objectForKey:@"media"]; NSDictionary *relevantObject = [media objectAtIndex:0]; NSString *expandedUrl = [relevantObject objectForKey:@"expanded_url"]; 

The main risk is that the web service may return an empty array for media , causing objectAtIndex:0 throw an exception or return something other than the array as the root object or in some other way to adjust the type somewhere along the line . Objective-C's usual nil messaging rules should save you most of the problems with dictionaries. It is enough how validation for the application is to call the court.

+7
source

Source: https://habr.com/ru/post/1383672/


All Articles