how to parse complex json data in iOS? - ios

I am new to iOS and I want to parse data but it is so complex, I don't know how to parse it. Below given is the json data.
{
"response_code": 200,
"last_updated": {
"date": "2015-12-27",
"time": "01:32:13"
},
"trains": [
{
"train": {
"number": "04921",
"start_time": "04:45",
"name": "SRE-UMB MEMU SPECIAL",
"type": "HSP"
},
"dest": {
"code": "UMB",
"name": "AMBALA CANT JN"
},
"source": {
"code": "SRE",
"name": "SAHARANPUR"
}
},
{
"train": {
"number": "04922",
"start_time": "20:45",
"name": "UMB-SRE MEMU SPECIAL",
"type": "HSP"
},
"dest": {
"code": "SRE",
"name": "SAHARANPUR"
},
"source": {
"code": "UMB",
"name": "AMBALA CANT JN"
}
}
]
}

{ , , } - it's a dictionary
[ , , ] - it's an array
In your case you get:
First level - dictionary with keys response_code, last_updated, trains.
Where:
response_code - value
last_updated - dictionary with keys date, time
trains - array of dictionaries with keys train, dest, source
etc.

Use the NSJSONSerialization class, it's easy.
For example, in Objective-C:
id jsonObject = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
if (jsonObject) {
// jsonObject is an NSArray or NSDictionary representation of the data that you can now do something with
}

Related

Filter Data in SwiftyJson

I have one SwiftyJson object.
I can not filter that array. I have tried this solution https://stackoverflow.com/a/37497170/4831567. But my json format is different that's why not working.
[
{
"name": "19860",
"header": {
"start_time": "1519270200",
"end_time": "1519299000",
"state": "lunch"
},
"alerts": "1",
"venue": {
"location": "Delhi, India",
"timezone": "+05:30"
},
"srs_category": [
0,
1
]
},
{
"name": "19861",
"header": {
"start_time": "1519270200",
"end_time": "1519299000",
"state": "Dinner"
},
"alerts": "1",
"venue": {
"location": "Mumbai, India",
"timezone": "+05:30"
},
"srs_category": [
1,
3
]
},
{
"name": "19862",
"header": {
"start_time": "1519270200",
"end_time": "1519299000",
"state": "lunch"
},
"alerts": "1",
"venue": {
"location": "Surat, India",
"timezone": "+05:30"
},
"srs_category": [
0,
2
]
}
]
i want to find that object that srs_category contain 1. I know it is possible by looping and condition. But i want via NSPredicate. If it is possible then please help me.
Thank You.
Here is easy way to use SwiftyJSON:
let filtered = JSON(yourArray).arrayValue.filter({
$0["srs_category"].arrayValue.map({ $0.intValue }).contains(1)
})
Use a Swift native function rather than NSPredicate
data represents the Data object received from somewhere
do {
if let json = try JSONSerialization.jsonObject(with:data) as? [[String:Any]] {
let srsCategory1 = json.first(where: { dict -> Bool in
guard let array = dict["srs_category"] as? [Int] else { return false }
return array.contains(1)
})
print(srsCategory1 ?? "not found")
}
} catch {
print(error)
}
If there are multiple items which can match the condition replace first with filter. Then the result is a non-optional array.

JSON - Count number of items in Ruby

I have a Json object as follows:
jsonobject = {
"fruits": [
{
"name": "A",
"uri": "a.com"
},
{
"name": "B",
"uri": "b.com"
}
],
"trees": [
{
"name": "t1",
"uri": "t1.com",
"status": null
},
{
"name": "t2",
"uri": "t2.com",
"status": null
}
]
}
How to get the number of trees/fruits in Ruby?
First of all, a small correction. Your jsonobject should be a string. Enclose the entire jsonobject in single quotes.
jsonobject = '{"fruits": [{"name": "A","uri": "a.com"},{"name": "B","uri": "b.com"}],"trees": [{"name": "t1","uri": "t1.com","status": null},{"name": "t2","uri": "t2.com","status": null}]}'
You can make use of the JSON library of ruby here...
number of trees
JSON.parse(jsonobject)["trees"].size
number of fruits
JSON.parse(jsonobject)["fruits"].size
UPDATE:
How to make the jsonobject as string
jsonobject = %q({"fruits": [{"name": "A","uri": "a.com"},{"name": "B","uri": "b.com"}],"trees": [{"name": "t1","uri": "t1.com","status": null},{"name": "t2","uri": "t2.com","status": null}]})

iOS JSON Parsing, array with multiple array

I have a JSON array with multiple object and I don't know how do I grab the "url" tag as an NSArray or a NSDictionary and show that image url in Tableview. I can't change the JSON data format.How should I do this?
Here is what the JSON response looks like:
{
"meta": {
"total_count": 10
},
"pages": [
{
"id": 7,
"meta": {
"type": "dashboard.NewsEvents",
"detail_url": "http://suno.to/api/v1/pages/7/"
},
"title": "NoEvent",
"created_at": "2016-03-06T10:42:19.646000Z",
"cover_url": [
[
{
"url": "/media/images/Maha_Shivratri2.original.jpg",
"title": "Maha Shivratri2.jpg"
},
{
"url": "/media/images/Maha_Shivratri1.original.jpg",
"title": "Maha Shivratri1.jpg"
}
],
[
{
"url": "/media/images/Celebrations.original.jpg",
"title": "Celebrations.jpg"
},
{
"url": "/media/images/Crew.original.jpg",
"title": "Crew.jpg"
},
{
"url": "/media/images/World_record.original.jpg",
"title": "World record.jpg"
},
{
"url": "/media/images/AI_pilots.original.jpg",
"title": "AI pilots.jpg"
}
],
[
{
"url": "/media/images/CbVv-VbWEAAmwv_.original.jpg",
"title": "DAL SWARAJ YATRA"
},
{
"url": "/media/images/CbVv_-TWwAE7RjM.original.jpg",
"title": "DAL SWARAJ YATRA"
},
{
"url": "/media/images/CbVv_SmXIAALQP8.original.jpg",
"title": "DAL SWARAJ YATRA"
},
{
"url": "/media/images/CahEc--UkAArc_z.original.jpg",
"title": "DAL SWARAJ YATRA"
}
]
]
},
{
"id": 2530,
"meta": {
"type": "dashboard.NewsEvents",
"detail_url": "http://suno.to/api/v1/pages/2530/"
},
"title": "World Culture Festival",
"created_at": "2016-03-12T06:59:21.023000Z",
"cover_url": [
[
{
"url": "/media/images/Security.original.jpg",
"title": "Security check"
}
],
[
{
"url": "/media/images/Elephant_statues.original.jpg",
"title": "Elephant"
}
],
[
{
"url": "/media/images/6.original.jpg",
"title": "Stage"
},
{
"url": "/media/images/4.original.jpg",
"title": "Stage"
}
]
]
},
{
"id": 2675,
"meta": {
"type": "dashboard.NewsEvents",
"detail_url": "http://suno.to/api/v1/pages/2675/"
},
"title": "Holi in Barsana",
"created_at": "2016-03-17T12:35:09.308000Z",
"cover_url": [
[
{
"url": "/media/images/Brajwasi_playing_holi_.original.jpg",
"title": "Holi in Barsana"
},
{
"url": "/media/images/dancing_.original.jpg",
"title": "Holi in Barsana"
},
{
"url": "/media/images/holi.._.original.jpg",
"title": "Holi in Barsana"
},
{
"url": "/media/images/holi..._.original.jpg",
"title": "Holi in Barsana"
}
],
[
{
"url": "/media/images/Lathmar_holi_19_n54f7LJ.original.jpg",
"title": "Lathmar Holi in Barsana"
}
],
[
{
"url": "/media/images/Lathmar_holi_17.original.jpg",
"title": "Lathmar Holi in Barsana"
},
{
"url": "/media/images/Lathmar_holi_20.original.jpg",
"title": "Lathmar Holi in Barsana"
}
]
]
},
I'm using this code to get the "url" array. Plz correct me ?
NSArray *imageUrlArray = [[self.jsonData objectAtIndex:indexPath.row]objectForKey:#"cover_url"];
NSLog(#"IMAGE URL ARRAY:%#",imageUrlArray);
NSString *imageUrl = [imageUrlArray valueForKey:#"url"];
NSLog(#"IMAGE URL:%#",imageUrl);
To view the JSON structure - http://jsonviewer.stack.hu/
NSMutableArray* imageurlArray = [NSMutableArray new];
NSArray* jsonArray = jsonData[#"pages"];
for (int i = 0; i<[jsonArray count]; i++) {
NSArray* coverUrlArray = jsonArray[i][#"cover_url"];
for (int t = 0; t< [coverUrlArray count]; t++) {
NSArray* UrlArray = coverUrlArray[t];
for (int x = 0; x<[UrlArray count]; x++) {
[imageurlArray addObject:UrlArray[x][#"url"]];
}
}
}
NSLog(#"imageurlArray: %#", imageurlArray);
//imageurlArray contains all url
//In cell for row at indexpath --> use imageurlArray[indexPath.row];
You have array wrappped by another array.
So, use this direction:
NSDictionary *json=//..initialized
NSArray *pages = [json valueForKey#"pages"];
NSDictionary *page = [pages objectAtIndex:0];
NSArray *ar1 = [page valueForKey#"cover_url"];
NSArray *ar2 = [ar1 objectAtIndex:0];
NSDictionary *elem = [ar2 objectAtIndex:0];
NSString *value = [elem valueForKey#"url"];
I would suggest using Mantel or JSONModel libraries for parsing objects and having decent DTOs.
When you deal with something like this, i suggest putting the complete json in http://jsonviewer.stack.hu/ so you can see the correct structure without getting confused.
Then it's just a matter of digging. When you see { }, you add a dictionary, when you see [ ], you add an array, until you reach your url object :)
I'm not writing the code because it is pretty trivial, just a mix of objectForKeys for dictionaries and objectAtIndex for arrays.
The last layers are just objects, so they're handled like any other object.
If you're confused about json, I suggest you try giving your json-parser a simple json (you hard core it yourself just above, its really just for testing).
Small advice :
Give it a simple array of 1 object, then 2, then put the array in a dict, then two, etc. and you keep making the json more complex until you really understand how it works. Then you'll eventually have a fake json just like your real one, and you can remove the fake and use the real one :)
Other advice :
There are many json parsing libraries that let you create the object model, where you can create (for example) a Page object that has an ID, a title, a cover URl, etc. that matches the JSON structure, and then you just tell the parser " make that JSON a Page!" and voilà, you have a Page. I don't know any of those json libraries in ios, but people will surely link it here, so try it out ! They're super easy to use and make json parsing really straightforward. And also, you don't have to map everything manually like you're doing ;)

Pulling Data from an NSDictionary

So I have an NSDictionary that has a variety of data within it. When printed to the log, it prints like this:
[{"user_id":3016817,"grade":"A","percent":"93","grading_periods":[{"assignments":[{"points":100.0,"grade":"A","score":95.0,"percent":"93","comment":null,"id":3268180},{"points":100.0,"grade":"A","score":90.0,"percent":"93","comment":null,"id":3268181}],"grade":"A","percent":"93","name":"Default"}]},{"user_id":3016818,"grade":"A","percent":"94","grading_periods":[{"assignments":[{"points":100.0,"grade":"A","score":92.0,"percent":"94","comment":null,"id":3268180},{"points":100.0,"grade":"A","score":95.0,"percent":"94","comment":null,"id":3268181}],"grade":"A","percent":"94","name":"Default"}]}]
If I use a formatter online, its a lot more readable and looks something like this:
[
{
"user_id": 3016817,
"grade": "A",
"percent": "93",
"grading_periods": [
{
"assignments": [
{
"points": 100,
"grade": "A",
"score": 95,
"percent": "93",
"comment": null,
"id": 3268180
},
{
"points": 100,
"grade": "A",
"score": 90,
"percent": "93",
"comment": null,
"id": 3268181
}
],
"grade": "A",
"percent": "93",
"name": "Default"
}
]
},
{
"user_id": 3016818,
"grade": "A",
"percent": "94",
"grading_periods": [
{
"assignments": [
{
"points": 100,
"grade": "A",
"score": 92,
"percent": "94",
"comment": null,
"id": 3268180
},
{
"points": 100,
"grade": "A",
"score": 95,
"percent": "94",
"comment": null,
"id": 3268181
}
],
"grade": "A",
"percent": "94",
"name": "Default"
}
]
}
]
My question would be how would I access the value of grade or score for a specific user_id using this dictionary?
Your string represents a NSArray, not a NSDictionary. And it's a JSON string, so you can parse it using NSJSONSerialization:
NSString *jsonString = #"..." // your string here
// Create array from json string
NSArray *jsonArray = [NSJSONSerialization
JSONObjectWithData:[jsonString dataUsingEncoding:NSUTF8StringEncoding]
options:NSJSONReadingMutableContainers
error:Nil];
// Loop to find your user_id
// Because each child of this array is a dictionary
for (NSDictionary *dic in jsonArray) {
if ([dic[#"user_id"] isEqual:#3016817]) { // user_id field is number
// Access what you want
NSString *grade = dic[#"grade"];
// For "score" you must go deeper
// Just remember, [] is array and {} is dictionary
}
}
A simple way to do this would be
for (NSDictionary* d in theArray) {
if ([d[#"user_id"] isEqualToString: u]) {
// do something
}
}
And matt is right, it is an array of dictionaries, no matter what type you declared to be.
You can use below class method of NSJsonSerialization class to create NSArray which will contain all the dictionaries.
+ (id)JSONObjectWithData:(NSData *)data options:(NSJSONReadingOptions)opt error:(NSError **)error;
Once you get the array of dictionaries from JSON, you can do following:
NSArray *filteredjsonArr = [jsonArr filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"user_id == %#", #"3016818"]];
NSDictionary *dict = [filtered firstObject];
if (dict != nil) {
NSString *grade = [dict objectForKey:#"grade"];
NSArray *gradingPeriods = [dict objectForKey:#"grading_periods"];
}
To access score and grade for specific assignments, you'll need to drill down further into gradingPeriods array.

JSON array Parsing issue in iOS

I've got a JSON Request that I'm able to add to an NSDictionary but I'm unable to access part of the JSON string. Here is a sample
{
"Resp": {
"Success": "True",
"who": {
"userid": 234,
},
"students": [
{
"ID": 1,
"name": John
},
{
"ID": 2,
"name": Jane
}
],
}
}
I am storing the data in an NSMutableDictionary and then passing that to my function which should run through each student and process them accordingly.
Here is what I've got so far and it's not working:
-(void)foo:(NSMutableDictionary*)json {
NSArray *students = json[#"students"];
for(NSMutableDictionary *student in students) {
NSLog(#"student id: %#", student[#"ID"]);
}
}
When debugging I can see the JSON object and students belongs under Resp as a value.
First of all, check your JSON on the validity http://jsonlint.com . It corrected your JSON with next modifications:
{
"Resp": {
"Success": "True",
"who": {
"userid": 234
},
"students": [
{
"ID": 1,
"name": "John"
},
{
"ID": 2,
"name": "Jane"
}
]
}
}
Then you should access your elements in right way:
- (void)foo:(NSMutableDictionary *)json {
NSArray *students = json[#"Resp"][#"students"];
for(NSDictionary *student in students) {
NSLog(#"student id: %#", student[#"ID"]);
}
}
For now it should be working.

Resources