Objective C - how to Json Parse a dictionary having many dictionaries inside it? - objective-c

Here is the main dictionary - 'query'.
I want to access 'results'- It is a NSDictionary having some key - pair values.
But, all the elements of 'query' dictionary (i.e count, results, created, lang, diagnostics) are inside 'query' dictionary's 0th element.
This is what I have written to access 'results'.
NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"restuarant" ofType:#"json"]];
//query is main NSDictionary
self.query = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
//results is an NSDictionary
self.results = [_query valueForKey:#"results"][0];
But, when I debug it, everything is getting saved in 'query' variable but nothing is getting stored in 'results' variable.
I also tried the following code, but that didn't work out as well -
self.results = [_query valueForKey:#"results"];
I have looked upon many other stackoverflow pages, but none of them suit my needs. Regards.

From what I understand, it should be something like:
//results is an NSDictionary
self.results = [[_query valueForKey:#"query"] valueForKey:#"results"];
To debug it easier and to understand better the structure, you can also break the access to the results dictionary, into multiple steps, like:
NSDictionary *queryDictionary = [_query valueForKey:#"query"];
self.results = [queryDictionary valueForKey:#"results"];
then you can check what you have in the first dictionary and then in the second one.
Hope this helps!

Related

Cocoa Touch JSON Handling

I've been looking for a while now and I can't seem to find a solution.
I am trying to format a JSON object that is being held in an NSData *receivedData.
The format of the JSON is:
[
{
"name":"Stephen",
"nickname":"Bob"
},
{
"name":"Rob",
"nickname":"Mike"
},
{
"name":"Arya",
"nickname":"Jane"
}
]
Normally I would use "NSJSONSerialization JSONObjectWithData:" of the NSDictionary. Then I would normally take the root of the JSON (in this case it would be something like "People":) and create the array from that root object. However as you can see this response is simply an array without a root object. I'm not sure how to handle this. The end goal is to have an array of Person objects, populated with the data in the JSON.
Edit: I would also like to add that I want to keep it native without third party libraries.
OK for anyone reading this. I just figured it out. Instead of formatting the initial NSData into a dictionary, you put that straight into an array. Then create a dictionary for each object in the array. Like so:
NSArray *response = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSDictionary* json = [responseArray objectAtIndex:0];
NSLog (#"%#",[json objectForKey:#"nickname"]);

Converting a JSON string into NSDictionary [closed]

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I'm trying to build an app in which people can order goods from different stores. I am totally new to programming, and I thought building a project like this would be a good way to learn it.
I'm stuck at the part of my app where a user can search for a company (on company name, location, or both) in my database. The database returns a JSON string, containing the company name and location for all found companies, which looks like this:
{"companyName":"testcompany_1","companyCity":"Tiel"},
{"companyName":"tectcompany_2","companyCity":"Tiel"}
So far so good!
now I want to turn this JSON string, which is an NSString, into an NSDictionary, in order to display the names and locations of the found companies in a tableView. This is where I get stuck.
I have been searching through StackOverflow, google, etcetera, and I have tried several ways to do this, for example:
Convert NSString to NSDictionary separated by specific character
Convert JSON feed to NSDictionary
Since none of the tutorials/answers is saw really solves my problem, I tried to make something out of them myself, and this is the result of that:
NSString *strURL = [NSString stringWithFormat:#"http://www.imagine-app.nl/companySearch.php?companyNameSearchField=%#&companyCitySearchField=%#", companyNameSearchField.text, companyCitySearchField.text];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSArray *companies = [inputString componentsSeparatedByString:#"},{"];
NSDictionary *dictionary = [NSJSONSerialization JSONObjectWithData:[NSData dataWithContentsOfFile:companies] options:kNilOptions error:nil];
To me, this makes sense. First, turn an NSString into an NSArray to separate objects, and after that convert the string into an NSDictionary, which can be used by the tableview I want to populate with this.
But when I log the dictionary, it says null, so no NSDictionary seems to be made by this code.
Now after several weeks of trying and searching, i'm starting to feel pretty stupid and desperate because I cannot find a good way to do this.
Does anyone know bow to turn a json string as shown above, into an NSDictionary?
What you want to do is the following:
NSURL *anURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://www.imagine-app.nl/companySearch.php?companyNameSearchField=%#&companyCitySearchField=%#", companyNameSearchField.text, companyCitySearchField.text]];
NSData *jsonData = [NSData dataWithContentsOfURL:anURL];
NSArray *mainArray = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL];
// In mainArray are NSDictionaries
for (NSDictionary *informationOnOneCompany in mainArray) {
NSString *name = informationOnOneCompany[#"companyName"];
NSString *city = informationOnOneCompany[#"companyCity"];
// Now you can store these two strings in that array or whatever populates your tableview ;)
}
Lets have a look at the steps:
We create an NSURL instance with the link we want.
We download the contents of that link into an NSData object.
We know how the JSON we receive looks like and identify that the "top layer" is an array. So we create an NSArray and initialize it with the JSON we received.
The curly braces and the colons in the JSON you posted tell us that in that array we created are instances of NSDictionary.
We loop through the NSArray using fast enumeration.
In every NSDictionary we look at the keys "companyName" and "companyCity" and store their values in an NSString.
Not implemented in the code above: You can populate your NSArray which is the datasource of your tableView
Hope that helps, if you have questions let me know ;)
No, it doesn't make sense at all, at several places. For example:
[NSData dataWithContentsOfFile:companies]
Huh, what? companies is an NSArray containing NSStrings - it's not a file path which points to a file you could initialize the data object with.
(It seems you're making assumptions about what the individual methods do - why that? It would be better to read the documentation - you wouldn't waste your and our time.)
The text/data you presented in the question is also not valid JSON. The only thing I can imagine is that the web service does indeed return valid JSON, i. e. the comma-separated dictionaries are correctly wrapped between [ ] to form an array, you just forgot to include them. In this case, you don't have to rape the string and poor Foundation framework, just convert the JSON to an array and it will be fine:
NSURL *url = [NSURL URLWithString:#"http://example.com/foo.json"];
NSData *data = [NSData dataWithContentsofURL:url];
NSArray *response = [NSJSONSerialization jsonObjectWithData:data options:kNilOptions error:NULL];

JSON format issue

I am new to web services and have GET working fine. When I try to POST I am sending this JSON string:
{"frequency":"None","leader":"test#test.com"}
But the server is expecting this:
{
"meta":
{"limit": 20, "total_count": 2},
"objects":
[{"frequency": "None", "leader": "jsmith#gmail.com"},
{"frequency": "None", "leader": "jsmith#gmail.com"}]
}
In my NewMeetingRK object I am trying to map to the "objects" as follows:
mgr.serializationMIMEType = RKMIMETypeJSON;
RKObjectMapping* newmtg = [RKObjectMapping mappingForClass:[NSMutableDictionary class]];
[newmtg mapKeyPath: #"frequency" toAttribute:#"repeat" ];
[newmtg mapKeyPath: #"leader" toAttribute:#"leader" ];
RKObjectMapping* newmtgSerializeMapping = [newmtg inverseMapping];
[mgr.mappingProvider setSerializationMapping:newmtgSerializeMapping forClass:[NewMeetingRK class]];
[mgr.mappingProvider setMapping:newmtgSerializeMapping forKeyPath:#"objects"];
[mgr.router routeClass:[NewMeetingRK class] toResourcePath:#"" forMethod:RKRequestMethodPOST];
This isn't working. I tried changing toResourcePath to #"/objects" but that didn't work either. Any idea how to send the values to the second set of JSON values on the server?
---EDIT----
I was missing the array as #HotLicks pointed out - thanks. But I still can't get my simple post with JSON values to work.
Instead of RKObjectManager can I do something simple with RKClient like this?
client = [RKClient clientWithBaseURL:[RKURL URLWithBaseURLString:#"https://appzute.appspot.com"]];
NSLog(#"I am your RKClient singleton : %#", [RKClient sharedClient]);
client.requestQueue.showsNetworkActivityIndicatorWhenBusy = YES;
[client setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSMutableArray *meetingArray = [NSMutableArray arrayWithCapacity:100];
[meetingArray addObject:[NSMutableDictionary dictionaryWithObjectsAndKeys:
self.leaderEmail.text, #"leader",
self.repeatLabel.text, #"frequency",
nil]];
NSDictionary *jsonDictionary = [NSDictionary dictionaryWithObjectsAndKeys:meetingArray, #"objects", nil];
NSString *jsonString = [jsonDictionary JSONRepresentation];
NSLog (#"jsonString is: %#",jsonString);
[client post:#"/api/meeting/?format=json&username=testuser#test.com&api_key=sdf7asd87fs8df78sdf" params:jsonString delegate:self];
The value of jsonString looks perfect: {"objects":[{"leader":"me#me.com","frequency":"None"}]}
The issue is that params:jsonString is not valid, because it needs an object not a string. But if I use params: jsonDictionary then I get this log file:
Sent RKRequest: objects[][leader]=me%40me.com&objects[][frequency]=None
I restkit.network:RKRequest.m:676 Status Code: 500
What could I possibly be doing wrong?
Thanks!
Unfamiliar with that JSON toolkit, but generally what you'd do is create two dictionaries, one for each of your "objects", place them in an array (your "objects" array). Then create a dictionary for your "meta" info. Finally, create a dictionary to contain the "meta" info and the "objects" array.
JSON maps almost perfectly to NSDictionary/NSArray, so there's not really any need to use a toolkit that uses "wrapper" objects.

Objective C, NSDictionary loop through each object

I am new to Facebook Developer. I want to create Mac OSX application using Facebook API. When i request FQL and its return me JSON data only like below:
My Code:
[self.result_text setString:[NSString stringWithFormat:#"%#",[result objectForKey: #"result"]];
It display:
[{"name":"My Name","first_name":"My First Name","last_name":"My Last Name"}]
I want to read the object inside this Dictionary. Example I just want to display "My Name" string. But I don't know how to it.
Thanks,
As Ashley Mills wrote, you should check the documentation. You can loop through the all dictionary keys like this:
for ( NSString *key in [dictionary allKeys]) {
//do what you want to do with items
NSLog(#"%#", [dictionary objectForKey:key]);
}
Hope it helps
You can parse the JSON contents from the server into a NSDictionary object via Lion's brand new NSJSONSerialization class (documentation linked for you).
e.g.
NSDictionary *jsonDictionary = [NSJSONSerialization JSONObjectWithData: [self.result_text dataUsingEncoding: NSUTF8StringEncoding] options: nil error: &error];
And once you have it in a NSDictionary object, it's easy to do something like:
NSString * myLastNameContent = [jsonDictionary objectForKey: #"last_name"];
Sergio's answer (which he keeps editing, even as I type :-) is very good too. +1 to him.
You can use JSONKit to transform the JSON string into a dictionary:
NSDictionary *resultsDictionary = [resultString
objectFromJSONStringWithParseOptions:JKParseOptionLooseUnicode|JKParseOptionValidFlags error:&err];
NSString* name = [resultDictionary objectForKey:#"name"];
JSONKit is straightforward to use and will make your application work also on older SDK versions.
You should read the documentation for NSDictionary here:
https://developer.apple.com/library/mac/#documentation/Cocoa/Reference/Foundation/Classes/nsdictionary_Class/Reference/Reference.html
in particular the section titled Accessing Keys and Values

xpath Table Contents into an array

How would I use xPath under the hpple Objective-C wrapper to extract the elements out of this table. Ideally I would like to put the addresses and prices into an array or dictionary.
I have been attempting to use the hpple objective c wrapper to pull the data out of the table located here: http://www.gaspry.com/index.php?zipcode=02169&action=search but haven't succeeded in getting the correct xpath query to pull out the information. Ideally, I would like to store this information in a set of arrays one, for addresses, and one for each of the prices. I am stuck on how to retrieve all of the information from the table and am unsure that my xPath is correct
My Code Thus Far is:
- (void)viewDidLoad {
[super viewDidLoad];
//Url Information
NSString *urlAddress = #"http://www.gaspry.com/index.php?zipcode=02169&action=search";
NSURL *url = [NSURL URLWithString:urlAddress];
NSData *htmlData = [[NSData alloc] initWithContentsOfURL:url];
//Start Parsing
TFHpple *xpathParser = [[TFHpple alloc] initWithHTMLData:htmlData];
NSArray *elements = [xpathParser search:#"//tBody[tr]"]; // get the table information
TFHppleElement *element = [elements objectAtIndex:0];
NSString *bodyTag = [element content];
NSLog(#"%#", bodyTag);
[xpathParser release];
[htmlData release];
}
One advice, a search path is case sensitive so make sure you use right one.
search query for :
#"//tbody//tr[1]//td[1]"
will get you address and change column "td[#]" to access other things you may want to store.
I'm not sure but address won't be parse correctly, that is, above search query will result after
tag but won't give you content before tag.
Hope this help :D