Parsing JSON: brackets in response - iphone

I want to parse this JSON YouTube recently featured.
This is how I get the title of the videos:
NSString *response = [request responseString];
responseDict = [response JSONValue];
videoTitleArray = [responseDict valueForKeyPath:#"feed.entry.title.$t"];
And it works like I want it.
But I also want to display the author of the video.
But the following code for this does not work properly:
videoAuthorArray = [responseDict valueForKeyPath:#"feed.entry.author.name.$t"];
NSLog(#"%#", videoAuthorArray);
The list of the authors I get looks like this:
(
author 1
),
(
author 2
),
(
author 3
),
(
author 4
),
I can't display the names in for example a table view because of the brackets.
How can I display the author names like the video titles?

When you see an Author you see this:
"author":[{"name":{"$t":"mls"},"uri":{"$t":"http://gdata.youtube.com/feeds/api/users/mls"},"yt$userId":{"$t":"SZbXT5TLLW_i-5W8FZpFsg"}}]
this means: author is an array of author objects
each author object has: name object, a uri object and a yt$userId object
each of this objects described above is a NSDictionary
formated we have:
"author":[
{
"name": {
"$t":"mls"
},
"uri": {
"$t":"http://gdata.youtube.com/feeds/api/users/mls"
},
"yt$userId":{
"$t":"SZbXT5TLLW_i-5W8FZpFsg"
}
}
],
so if you have your videoAuthorArray each element is an NSDictionary and has this keys: name, uri and yt$userId
each of this objects has an NSDictionary with a single key: $t witch has the value

Related

AFNetworking valueForKeyPath Wildcard

Im trying to get the tvrage_name from the following JSON file.
{
data: {
Band of Brothers: {
air_by_date: 0,
cache: {
banner: 1,
poster: 1
},
language: "en",
network: "HBO",
next_ep_airdate: "",
paused: 0,
quality: "Any",
status: "Ended",
tvdbid: 74205,
tvrage_id: 2708,
tvrage_name: "Band of Brothers"
},
Breaking Bad: {
air_by_date: 0,
cache: {
banner: 1,
poster: 1
},
language: "en",
network: "AMC",
next_ep_airdate: "2013-07-14",
paused: 0,
quality: "HD",
status: "Continuing",
tvdbid: 81189,
tvrage_id: 18164,
tvrage_name: "Breaking Bad"
},
},
message: "",
result: "success"
}
Is there any way to have a wildcard in the valueForKeyPath?
So the valueForKeyPath would be: data.*.tvrage_name (the * would be the wildcard)
No. You will have to loop over the key/values like this*:
...
NSDictionary *data = [JSON valueForKey:#"data"];
for (NSString *movie in data) {
NSLog(#"tvrage_name: %#", [[data valueForKey:movie] valueForKey:#"tvrage_name"]);
}
...
*I like to be on the safe side so I always have extra checks. e.g. [JSON isKindOfClass:[NSDictionary class]], etc.
Hope it helps.
If you get a copy of the dictionary with just the tv show entries (not 'message' and 'result'), then you can do [[shows allValues] valueForKeyPath:#"tvrage_name"]
This should work since allValues gives you an array of dictionaries and so valueForKeyPath will in turn give you an array of values under the given key.
(However it's probably a bad idea to do this without additional checks or hardening when getting JSON over a network, in case the JSON is not structured as you expected)

Sort/group NSDictionary by key

i have data in NSDictionary like below :
Value : Football, Key: SPORT
Value : Cricket, Key: SPORT
Value : Fastrack, Key: PRODUCT/SERVICE
Value : Audi USA, Key: CARS
Value : BMW, Key: CARS
Value : Facebook, Key: PRODUCT/SERVICE
Value : TED, Key: WEBSITE
Value : National Geographic, Key: MEDIA/NEWS/PUBLISHING
Value : MyWebProduct, Key: WEBSITE
i want grouping of values according to key. what i need to do in this case or another suitable idea to implement this. I want result to be display something like :
SPORT : Football, Cricket
CARS : Audi, BMW
...
any help appreciable ...
Since you have multiple objects grouped under the same key, a dictionary of arrays would be a suitable structure to contain your data.
NSMutableDictionary *dict = [ [ NSMutableDictionary alloc ] init ];
NSArray *myItems = [ [ NSArray alloc ] initWithObjects:#"item one", #"item two", nil ];
[ dict setObject:myItems forKey:#"group of items" ];
Then you can access the group using
[dict objectForKey:#"group of items"]
Would this work for you, as a category on NSMutableDictionary:
- (void)setObject:(id)object inArrayForKey:(id <NSCopying>)key
{
id current = [self objectForKey:key];
if (!current || ![current isKindOfClass:[NSArray class]]) {
[self setObject:#[object] forKey:key];
} else {
[self setObject:[(NSArray *)current arrayByAddingObject:object] forKey:key];
}
}
Basically, you would then have a clean interface adding an item into an array associated with the key. You could choose to only make it an array if there was more than one item, if that's your preference.
If you're not familiar with adding categories, they allow you to add methods to existing classes. In Xcode just do new file > objective-C category and add the category on NSMutableDictionary.
NSDictionary cannot be sorted by default. If you want sorted dictionary, go on and implement your own subclass of it (this is one of the few valid reasons for which you can subclass a standard container object).

Reading a JSON string

I have a JSON String, in the format;
{
"name": "Alex",
"age": "12"
}
I know how to extract values from the above JSON. but at times, when there are no records in the database. i get a null value printed. (i undestand that this is not a valid JSON)
This null gets caught in the following if-condition.
SBJsonParser *parser = [SBJsonParser new];
NSDictionary *content = [pobjectWithString:[request responseString]];
if(!content){
NSLog(#" when its null it comes to this block");
return;
}
I need to read this value null and save it in a NSString. How can i do this ?
note: i have made use of ASIHTTPRequest to write the above code.
It's not clear what you're asking for. I think you want to detect when a null occurs (which you already seem to do with if(!content) ), then you want to create a string that either is empty, or has the word "null" in it. Why not:
if(!content) {
return #"null";
}
Of course, you could return whatever you wanted in the string.

Parsing JSON ( again ) in iOS

I'm just playing with the JSON parser in iOS it's working fine as a ( simple ) example . But I was wonder how one would actually parse something (a bit) more complicated, the a Twitter trends JSON, like this :
{
"trends": {
"2011-03-13 11:42:17": [
{
"events": null,
"query": "Fukushima",
"promoted_content": null,
"name": "Fukushima"
},
{
"events": null,
"query": "Rebecca Black",
"promoted_content": null,
"name": "Rebecca Black"
},
{
"events": null,
"query": "Pearl Harbour",
"promoted_content": null,
"name": "Pearl Harbour"
},
...
{
"events": null,
"query": "Magdalena Neuner",
"promoted_content": null,
"name": "Magdalena Neuner"
}
]
},
"as_of": 1300016537
}
How would one just return the first 3 queries ? in this instance : Fukushima, Rebecca Black and Pearl Harbour .
Using the example code, it goes something like this :
for (int i = 0; i < [luckyNumbers count]; i++)
[text appendFormat:#"%#\n", [luckyNumbers objectAtIndex:i]];
This is for a much simpler feed though, can it be approached the same way for what I'm looking for ?
I'm trying to return the value of "query":
So I`m doing this :
NSLog(#"%#", [[luckyNumbers objectForKey:#"trends"]);
This of course logs the content of the key "trend", how do I go about returning not only the first ( and only ) key of trends but also dig one more level down to return the content of "query" ??
I've also tried something like this :
NSString *date = [[[luckyNumbers valueForKeyPath:#"trends"] allKeys] description];
NSArray *trends = [luckyNumbers objectForKey:#"trends"];
NSLog(#"%#", [trends valueForKeyPath:date]);
but no go ...
EDIT (aftet honcheng's answer):
Because I want to iterate through the results of "trends", I'm doing :
NSDictionary *luckyNumbers = [responseString JSONValue];
NSArray *keys = [[luckyNumbers objectForKey:#"trends"] allKeys];
for (int i =0; i < [keys count]; i++) {
NSLog(#"%#", [keys objectAtIndex:i]);
}
Obviously something is wrong because I'm not getting any result ..
JSON parser usually returns native NSObjects such as NSDictionary and NSArray. After parsing, you just have to treat it like a new object.
[luckyNumbers allKeys] returns an NSArray ["trends", "as_of"]
[[luckyNumbers objectForKey:#"trends"] allKeys"] returns an NSArray ["2011-03-13 11:42:17"]
Since allKeys returns an NSArray, you can just use a for loop to get all your keys.

How to read dictionary with child

Help me in reading this dictionary: (its an NSDictionary generated from XMLData)
Menus = {
Table1 = {
Phone = {
text = "\n (404) 371-1466";
};
text = "\n ";
};
text = "\n";
};
}
This should get you the phone number, for example:
NSString *phoneNum = [[[[dict objectForKey:#"Menus"] objectForKey:#"Table1"]
objectForKey:#"Phone"] objectForKey:#"text"];
You have one item in the dictionary - "Menus".
That single item is a dictionary, with two items - "Table 1" and "text". "Table 1" is a dictionary, "text" is an NSString.
Inside "Table 1", you have two items - "Phone" and "text". At this point, I think you can see the pattern...