I've got a question regarding parsing a JSON response within iOS5.
Currently, I'm following this guide here to help me parse the JSON response returned from a third-party mapping service.
Everything works, except that the JSON response returned by the third-party server is somewhat different from the one shown in the guide itself.
In a nutshell, the overall structure of the entire JSON response looks something like this:
{
"directions": [....],
"messages": [....],
"routes":
{
"features": [
{
"attributes": {....},
"geometry":
{
"paths": [....]
}
}
]
}
}
This is the actual JSON query URL.
By using this line of code,
NSDictionary * jsonResponse = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
I am able to sucessfully get the jsonResponse dictionary to report that it has 3 key/value pairs, but my ultimate goal is to retrieve the array stored in 'routes.features.geometry.paths'.
This is my current code block that gets the final set of array values:
NSDictionary * jsonResponse = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
NSArray * jsonArray = [jsonResponse valueForKeyPath:#"routes.features.geometry.paths"];
jsonArray = [jsonArray objectAtIndex:0];
jsonArray = [jsonArray objectAtIndex:0];
I was wondering if anyone might have a better idea of how I should go about doing this in a more elegant fashion?
Thanks a lot in advance!
You can't just use it as JSON object because it will be working as JSON (Plain String) and you need to parse it so for your problem you can do like this to directly go to paths
NSArray *arr = [[[[jsonResponse objectForKey:#"routes"] objectForKey:#"features"] objectForKey:#"geometry"] objectForKey:#"paths"];
Now you can access your paths data from "arr" array
UPDATE:
NSArray *arr = [[[[[jsonResponse objectForKey:#"routes"] objectForKey:#"features"] objectAtIndex:0] objectForKey:#"geometry"] objectForKey:#"paths"];
as features element is an Array so traverse array first then goto its elements
Related
I am working on an App and I use my JSON RESTful API. Therefor I parse JSON like in the following example:
NSData * apiReturn;
NSError *myError = nil;
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:apiReturn options:NSJSONReadingMutableLeaves error:&myError];
If I now pass the following JSON encoded String via the API to the App:
{"da": {"name":"dienstlicher Anlass", "duty":true, "type":"dropdown",
"values":{"gt":{"name":"Gesprächstermin", "recurring":true,
"values":{"fa":{"name":"Firma", "duty":true, "type":"text",
"multiline":false}, "ar":{"name":"Anrede", "duty":true, "single":true,
"type":"checkbox", "values":{"fr":{"name":"Frau"},
"hr":{"name":"Herr"}}}, "nm":{"name":"Gesprächspartner", "duty":true,
"type":"text", "multiline":false}, "bm":{"name":"Bemerkung",
"duty":false, "type":"text", "multiline":true}}}}
},"bm":{"name":"Bemerkung", "values":[],
"type":"text"},"bm2":{"name":"Bemerkung", "values":[], "type":"text"}}
(You can parse this a bit prettier here: http://json.parser.online.fr)
The NSDictionary should contain the following Keys: "da", "bm", "bm2" - Sorted this way, because this is the sorting of the JSON String!
But what Objective-C does, is this:
Why does Objective-C sort the elements, and why so wrong?
I hope you can help! :)
An NSDictionary is not guaranteed to store the keys in any given order.
I have a cuestion about parsing a Json strings.
If i'm getting a string like:
[["AR","Argentina","flag_of_argentina","en","F","1"],
["AU","Australia","flag_of_australia","en","B","4"]]
How can i save this string into an entity when normally i see Jsons that have something like this:
(
(
"Group_id": 1,
"Date" : "2014-04-08",
"Hour" : "18:00:00",
"Location":"Guayaquil, Ecuador",
"State" : A
),
...
If i have to make an array or something else to store it to the entity in core data how can i do it?
I hope my question is well made and I appreciate your help. Thank you very much.
Cocoa Touch provides a built in class that helps you serialize this data. It's called NSJSONSerialization.
So, that looks to me like you have arrays within an array. First you're going to want to convert the NSString to NSData:
NSData *JSONdata = [yourJSONString dataUsingEncoding:NSUTF8StringEncoding];
Then serialize it into an array:
NSArray *JSONArray = [NSJSONSerialization JSONObjectWithData:JSONdata options:NSJSONReadingMutableContainers error:&error];
Then you can access any subarray by writing:
NSArray *countryData = [JSONArray objectAtIndex:i];
And from there you can access the data that you need.
~
As for building JSON Data, you'll need to construct an NSMutableDictionary and populate it accordingly. Once you have that, use the same class NSJSONSerialization to convert it to a JSON string.
I get the JSON format like this:
stream( { posts: [{CHANNEL: {ios: "(format=m3u8-aapl).m3u8"} }]})
What I want to get is an array for the "ios".
This is my code:
id jsonObjects = [NSJSONSerialization JSONObjectWithData:
jsonSource options:NSJSONReadingMutableContainers error:nil];
for (NSDictionary *dataDict in jsonObjects) {
NSArray *ios_data = [[[dataDict objectForKey:#"posts"] objectForKey:#"CHANNEL"] objectForKey:#"ios"];
NSLog(#"%#",ios_data);
dict = [NSDictionary dictionaryWithObjectsAndKeys:ios_data, ios,nil];
}
but it return in NULL, what the problem of it?
Your "JSON":
stream( { posts: [{CHANNEL: {ios: "(format=m3u8-aapl).m3u8"} }]})
Is not JSON. You can try running it through a validator like http://jsonlint.com/ to test it out.
Also, you should create an NSError reference to pass in instead of nil so NSJSONSerialization can vend you an error object. This will help in your debugging.
Here is an example of what your data would look like if it were valid JSON:
{
"stream": [
{
"posts": [
{
"CHANNEL": {
"ios": "(format=m3u8-aapl).m3u8"
}
}
]
}
]
}
(I spaced it out to be more legible, but the spacing is unnecessary for parsing.)
Once you have your array holding 'posts' you can drill down like this:
NSArray *fileData = [myDic1 valueForKeyPath:#"posts.CHANNEL"];
and then access like this:
for (int i=0; i < [clientFileData count]; i++) {
NSDictionary *myDictionary = [fileData objectAtIndex:i];
]
Also, unless I am wrong, your JSON file seems incorrectly formatted.
Get your response like:
NSDictionary *dictionaryData = [NSJSONSerialization JSONObjectWithData:responseData options:kNilOptions error:&error];
Correct JSOn should be like this
{
"posts":[
{
"CHANNEL":{
"ios":"(format=m3u8-aapl).m3u8"
}
}
]
}
Get the correct format of JSON and then try to parse it. And one thing you were doing wrong is POST is an array.
I'm working with data from a Foursquare API.
I want to get a list of coffee shops, and am getting that back correctly (I'm using RestKit)... but once I get that list, on my end I need to filter out any coffee shop that is a "Starbucks".
So right now I only know how to pull in all coffee shops, but I don't know how to parse that data once I have it before I serve it into the app table view so that there will be no Starbucks coffee shops listed.
Any ideas how I could do that? Let me know if you need any of my code snippets posted that might help. Thanks!
EDIT
Normal response type from the API would be:
"venue": [{
"name": "ABC Coffee Shop", {
So I would need to take "name" and filter out any name that was "Starbucks".
If FourSquare doesn't let you apply a filter to the request, to filter on the name "Starbucks" then what I would do with this is the following.
I would start by deserializing the response into a JSON Object, which in this case will be a dictionary.
NSError *error = nil;
NSDictionary *responseDict = [[NSJSONSerialization JSONObjectWithData:foursquareResponse options:0 error: &error];
NSArray *starbucks = nil;
if (!error) {
NSArray *coffeeShops = responseDict[#"venue"];
starbucks = [coffeeShops filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"name = 'Starbucks'"]];
} else {
// handle the error
}
NSLog(#"Starbucks: %#", starbucks");
I didn't test this code but I think it should get you on your way.
Looks like JSON to me, you could just use the built in JSON parser, the NSJSONSerialization class. Here is a method I built that takes an NSData JSON parameter, deserializes it and returns a dictionary.
- (NSMutableDictionary *)deserialize: (NSData *)data {
return [[NSJSONSerialization JSONObjectWithData:data options:kNilOptions error: nil] mutableCopy];
}
I don't know the structure of Foursquare's response inside out, so you might want to NSLog() the returned dictionary to see how you can now reference to it.
I'm a noob when it comes to requests and JSON. Inside my app I send to the server and get back stuff so I can use it of course. I tried looking up different things but none really seem to be what I'm looking for. So I'm getting back what seems to be formatted JSON. What I want to know how to do is put it into a NSMutable array. The way I get this JSON is by using AFNetworking's AFJSONRequestOperation.
My response looks like this.
{
id = 38;
name = "St. Martin Hall";
},
{
id = 40;
name = "Assumptions Commons";
},
{
id = 41;
name = "Vickroy Hall";
},
{
id = 42;
name = "St. Ann Hall";
},
{
id = 37;
name = "Duquesne Towers";
}
if your JSON format like {"mainKey":[{},{},...]}
NSError* error;
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* dataArray = [json objectForKey:#"mainKey"]; //2
else your JSON format like [{},{},...]
NSError* error;
NSArray* dataArray = [NSJSONSerialization
JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
I think your format is case 2: [] Array of Object {}
Tutorial: http://www.raywenderlich.com/5492/working-with-json-in-ios-5
JSON:http://www.json.org
You use the NSJSONSerialization class to convert JSON to Foundation objects and convert Foundation objects to JSON.
This class is available in iOS 5.0+. If you're targetting older iOS version, have a look at a third-party JSON framework:
Comparison of JSON Parser for Objective-C (JSON Framework, YAJL, TouchJSON, etc)
If that's what you're getting back it's not JSON I'm afraid. It does look like Javascript in a way but it should be more like
[
{
"id" : 38,
"name" : "St. Martin Hall"
},
{
"id" : 39,
"name" : "Assumptions Commons"
}
]