-2

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:

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?

Community
  • 1
  • 1
Joris Dijkstra
  • 132
  • 4
  • 14

2 Answers2

2

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:

  1. We create an NSURL instance with the link we want.
  2. We download the contents of that link into an NSData object.
  3. 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.
  4. The curly braces and the colons in the JSON you posted tell us that in that array we created are instances of NSDictionary.
  5. We loop through the NSArray using fast enumeration.
  6. In every NSDictionary we look at the keys "companyName" and "companyCity" and store their values in an NSString.
  7. 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 ;)

HAS
  • 19,140
  • 6
  • 31
  • 53
  • this makes sense! but when I apply this method, and I try to log the jsonData, it gives me just a bunch of number instead of companies. also, it does not seem to make an array, because when I try to log the mainArray, it says null.. – Joris Dijkstra May 12 '13 at 19:33
  • Do you have control over the API of that site? Or is there any documentation? I just tried it again and you are right ... It is because you receive invalid `JSON` from server side... What I get when I send "Starbucks" and "Amsterdam" is `{"companies":[]}{"companies":[]}`. I put one's shirt on a horse that it worked when I posted this because I never post untested code ... – HAS May 12 '13 at 19:53
  • true, JSON is causing this problem. i'm editing my PHP code right now, if that doesn't work, I can show you if you want? – Joris Dijkstra May 12 '13 at 20:25
  • Sorry, but I think you need to search around (I think there's a ton of information here on SO or on the web) or if you don't find anything ask another question ... I don't have any idea of php right know, sorry... – HAS May 12 '13 at 20:29
  • I tried something: `NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];`. this converts the json into an nsstring. and when I log it, it gives me a nice array-looking string... that might be useful information? – Joris Dijkstra May 12 '13 at 20:30
  • That's exactly what gave me `{"companies":[]}{"companies":[]}` as I posted above ;). When you get your server returning the right JSON you should be able to use the code in my answer. If you have questions let me know ;) – HAS May 12 '13 at 20:33
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/29808/discussion-between-has-and-joris-dijkstra) – HAS May 12 '13 at 20:34
1

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];
  • Thank you for your quick response. As mentioned, I am a beginning programmer. I have read the documentation and several tutorials and answers, but since none of them covered my problem and everyone was doing it different, I composed this piece code myself. However, When I add you piece of code to my app, is shows an error and gets stuck. this is the error: `Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSConcreteData isFileURL]: unrecognized selector sent to instance 0x11676d00'` – Joris Dijkstra May 05 '13 at 09:35
  • @JorisDijkstra Then your array contains `NSData` objects and not strings. You can always google the exception message. –  May 05 '13 at 09:38
  • I know, busy with that right now but now answer solves it. any suggestions? – Joris Dijkstra May 05 '13 at 09:55