Incorrect conversion from object to JSON? - ios

I need to send to a web service this JSON by POST:
{
"plantilla" : "IL3\/il3_prof",
"contacto" : {
"email" : "vgonzalez#ub.edu",
"nombre" : "Vanesa",
"movilPersonal" : "934037680",
"apellidos" : "Gonzalez Jimenez."
"direccionTrabajoDTO" : {
"direccion" : "Feixa Llarga, S\/N 08970 Hospitalet De Llobregat (Barcelona), España"
},
},
"valoresPlantilla" : [
{
"key" : "nombre",
"value" : "Vanesa Gonzalez Jimenez."
},
{
"key" : "curso",
"value" : "Curs de test per Tecnologia"
},
{
"key" : "linked",
"value" : "es.linkedin.com\/in\/"
},
{
"key" : "direccion",
"value" : "Feixa Llarga, S\/N 08970 Hospitalet De Llobregat (Barcelona), España"
},
{
"key" : "email",
"value" : "vgonzalez#ub.edu"
},
{
"key" : "telefono",
"value" : "934037680"
}
]
}
I created the object Tarjeta with values:
Tarjeta *tarjeta = [[Tarjeta alloc] init];
tarjeta.plantilla = #"IL3/il3_prof";
Contacto *contacto = [[Contacto alloc] init];
contacto.nombre = #"Vanesa";
contacto.apellidos = #"Gonzalez Jimenez.";
contacto.email = #"vgonzalez#ub.edu";
contacto.movilPersonal = #"934037680";
DireccionTrabajo *direccionTrabajo = [[DireccionTrabajo alloc] init];
direccionTrabajo.direccion = #"Feixa Llarga, S/N 08970 Hospitalet De Llobregat (Barcelona), España";
contacto.direccionTrabajo = direccionTrabajo;
tarjeta.contacto = contacto;
ValorPlantilla *nombre = [[ValorPlantilla alloc] init];
nombre.key = #"nombre";
nombre.value = #"Vanesa Gonzalez Jimenez.";
ValorPlantilla *curso = [[ValorPlantilla alloc] init];
curso.key = #"curso";
curso.value = #"Curs de test per Tecnologia";
ValorPlantilla *linked = [[ValorPlantilla alloc] init];
linked.key = #"linked";
linked.value = #"es.linkedin.com/in/";
ValorPlantilla *direccion = [[ValorPlantilla alloc] init];
direccion.key = #"direccion";
direccion.value = #"Feixa Llarga, S/N 08970 Hospitalet De Llobregat (Barcelona), España";
ValorPlantilla *email = [[ValorPlantilla alloc] init];
email.key = #"email";
email.value = #"vgonzalez#ub.edu";
ValorPlantilla *telefono = [[ValorPlantilla alloc] init];
telefono.key = #"telefono";
telefono.value = #"934037680";
tarjeta.valoresPlantilla = [NSArray arrayWithObjects:nombre, curso, linked, direccion, email, telefono, nil];
return tarjeta;
After this, I do a conversion from object to JSON with this method:
NSMutableDictionary *tarjetaDict = [[NSMutableDictionary alloc] init];
[tarjetaDict setValue:tarjeta.plantilla forKey:#"plantilla"];
NSMutableDictionary *contactoDict = [[NSMutableDictionary alloc] init];
[contactoDict setValue:tarjeta.contacto.nombre forKey:#"nombre"];
[contactoDict setValue:tarjeta.contacto.apellidos forKey:#"apellidos"];
[contactoDict setValue:tarjeta.contacto.email forKey:#"email"];
[contactoDict setValue:tarjeta.contacto.movilPersonal forKey:#"movilPersonal"];
NSMutableDictionary *direccionDict = [[NSMutableDictionary alloc] init];
[direccionDict setValue:tarjeta.contacto.direccionTrabajo.direccion forKey:#"direccion"];
[contactoDict setValue:direccionDict forKey:#"direccionTrabajoDTO"];
[tarjetaDict setValue:contactoDict forKey:#"contacto"];
[tarjetaDict setValue:tarjeta.valoresPlantilla forKey:#"valoresPlantilla"];
return tarjetaDict;
When I finish this process, I send the NSMutableDictionary like JSON to the web service, but it says that's incorrect and this is the error.
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Invalid type in JSON write (ValorPlantilla)'
I'm doing anything wrong?

Add this method to your ValorPlantilla class
-(NSMutableDictionary *)getobject
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
[dict setObject:self.key forKey:#“key"];
[dict setObject:self.value forKey:#“value"];
return dict;
}
And Change this line
tarjeta.valoresPlantilla = [NSArray arrayWithObjects:[nombre getobject], [curso, linked getobject], [direccion getobject], [email getobject], [telefono getobject], nil];
This might works

First make below six individual dictionary,
{
"key" : "nombre",
"value" : "Vanesa Gonzalez Jimenez."
},
{
"key" : "curso",
"value" : "Curs de test per Tecnologia"
},
{
"key" : "linked",
"value" : "es.linkedin.com\/in\/"
},
{
"key" : "direccion",
"value" : "Feixa Llarga, S\/N 08970 Hospitalet De Llobregat (Barcelona), España"
},
{
"key" : "email",
"value" : "vgonzalez#ub.edu"
},
{
"key" : "telefono",
"value" : "934037680"
}
Then create one array let's say temp array, add this all six dictionary to that array.
Then make below dictionary let's say tempDic,
"contacto" : {
"email" : "vgonzalez#ub.edu",
"nombre" : "Vanesa",
"movilPersonal" : "934037680",
"apellidos" : "Gonzalez Jimenez."
"direccionTrabajoDTO" : {
"direccion" : "Feixa Llarga, S\/N 08970 Hospitalet De Llobregat (Barcelona), España"
},
},
It's having sub dictioanry.
Then make standard dictionary(final) and set three objects : plantilla, tempDic and temp array
So, your object is ready to send.
Now, don't convert it in json. Convert it in NSdata like below
If your final dictionary's name is finalDic then,
NSData *data = [NSJSONSerialization dataWithJSONObject:finalDic options:0 error:nil];
And send that data to server.
If you are using AFNetworking then you not need to convert finalDic to data. Afnetworking manage automatically, just pass that finalDict as parameter of webservice call by AFNetworking.
Hope this will help :)

Please check your json data wrong below url:
http://jsoneditoronline.org/
{
"plantilla" : "IL3\/il3_prof",
"contacto" : {
"email" : "vgonzalez#ub.edu",
"nombre" : "Vanesa",
"movilPersonal" : "934037680",
"apellidos" : "Gonzalez Jimenez.", //Please separate ','
"direccionTrabajoDTO" : {
"direccion" : "Feixa Llarga, S\/N 08970 Hospitalet De Llobregat (Barcelona), España"
} // Please remove separete
},
"valoresPlantilla" : [
{
"key" : "nombre",
"value" : "Vanesa Gonzalez Jimenez."
},
{
"key" : "curso",
"value" : "Curs de test per Tecnologia"
},
{
"key" : "linked",
"value" : "es.linkedin.com\/in\/"
},
{
"key" : "direccion",
"value" : "Feixa Llarga, S\/N 08970 Hospitalet De Llobregat (Barcelona), España"
},
{
"key" : "email",
"value" : "vgonzalez#ub.edu"
},
{
"key" : "telefono",
"value" : "934037680"
}
]
}

Related

mongodb shell to java driver aggregate statement

I'm able to run an aggregate MongoDb (3.8) request in the mongo shell but I can't get it out working using the java driver (3.4 java 8).
here's the input source structure. I want to aggregate informations to provide company activities stats. note that the ape document states for the company registered activity. I want to group on the first 3 digits of the ape code
{
"_id" : "00552017600016",
"sirene" : "005520176",
"nic" : "00016",
"natureCode" : "5710",
"natureLabel" : "SAS, société par actions simplifiée",
"name" : "HERNAS CARTONNAGE",
"brand" : "",
"registerDate" : ISODate("1954-12-31T23:00:00Z"),
"startDate" : ISODate("1954-12-31T23:00:00Z"),
"headquaters" : true,
"address" : {
"number" : 50,
"ext" : null,
"lane" : "RUE PASTEUR",
"zipcode" : "80210",
"city" : "FEUQUIERES EN VIMEU",
"country" : "FRANCE",
"location" : {
"type" : "Point",
"coordinates" : [
1.60319694244078,
50.0537636973407
],
"accuracy" : 0,
"ban" : "ADRNIVX_0000000260779642"
}
},
"ape" : {
"code" : "1721A",
"label" : "Fabrication de carton ondulé"
},
"staff" : {
"count" : 50,
"year" : 2016
}
}
running this commands in the shell works like a charm
db.companies_geo.aggregate([ {$match:{"address.city":"LE MANS"}},
{$group:{_id:{$substrBytes:["$ape.code",0,2]}, count:{$sum:1}, code:{$last:"$ape.code"}, label:{$last:"$ape.label"}}},
{$project:{count:1, code:1, label:1}},
{$sort:{count:-1}},
{$limit:20}
])
it produces this result
{ "_id" : "68", "count" : 4603, "code" : "6832B", "label" : "Supports juridiques de gestion de patrimoine immobilier" }
{ "_id" : "47", "count" : 1929, "code" : "4799B", "label" : "Vente par automate, aut. com. dét. hors mag., éventaire ou marché" }
{ "_id" : "94", "count" : 1874, "code" : "9499Z", "label" : "Autres organisations fonctionnant par adhésion volontaire" }
{ "_id" : "86", "count" : 1704, "code" : "8690F", "label" : "Activités de santé humaine non classées ailleurs" }
{ "_id" : "56", "count" : 832, "code" : "5630Z", "label" : "Débits de boissons" }
{ "_id" : "90", "count" : 816, "code" : "9004Z", "label" : "Gestion de salles de spectacles" }
{ "_id" : "85", "count" : 769, "code" : "8560Z", "label" : "Activités de soutien à l'enseignement" }
{ "_id" : "70", "count" : 592, "code" : "7022Z", "label" : "Conseil pour les affaires et autres conseils de gestion" }
{ "_id" : "96", "count" : 585, "code" : "9609Z", "label" : "Autres services personnels n.c.a." }
{ "_id" : "81", "count" : 582, "code" : "8130Z", "label" : "Services d'aménagement paysager" }
on the java side I've tried this but the code line bellow the while iteration raises the exception org.bson.codecs.configuration.CodecConfigurationException: Can't find a codec for class com.mongodb.client.model.BsonField.
private List<Document> cityActivityGraph() {
Bson filter = Filters.eq("address.city", "LE MANS");
BsonField id = new BsonField("_id", Filters.eq(new Document("$substrBytes", Arrays.asList("$ape.code", 0, 2))));
BsonField count = Accumulators.sum("count", 1);
BsonField label = Accumulators.last("ape.label", 1);
BsonField code = Accumulators.last("ape.code", 1);
Bson group = Aggregates.group(id, count, code, label);
Bson match = Aggregates.match(filter);
Bson projections = Projections.include("code", "label", "count");
Bson project = Aggregates.project(projections);
Bson sort = Sorts.descending("count");
MongoCursor<Document> cursor = getTable().aggregate(Arrays.asList(
Aggregates.match(match),
Aggregates.group(group),
Aggregates.project(project),
Aggregates.sort(sort))).iterator(); <--- exception here
List<Document> result = new ArrayList<>();
while (cursor.hasNext()) {
Document doc = cursor.next();
System.out.println(doc.toJson());
result.add(doc);
}
return result;
}
any idea ? thanks in advance
found a solution, perhaps not the most efficient but it works
Bson id = new Document("_id", new Document("$substrBytes", Arrays.asList("$ape.code", 0, 3)));
BsonField code = Accumulators.last("code", "$ape.code");
BsonField label = Accumulators.last("label", "$ape.label");
BsonField count = Accumulators.sum("count", 1);
Bson projections = Projections.include("code", "label", "count");
Bson sort = Sorts.descending("count");
AggregateIterable<Document> stats = getTable().aggregate(Arrays.asList(
Aggregates.match(filter),
Aggregates.group(id, code, label, count),
Aggregates.project(projections),
Aggregates.limit(limit),
Aggregates.sort(sort)
));
List<Document> result = new ArrayList<>();
for (Document d:stats) {
result.add(d);
}
return result;

Sort Array of dictionary in Swift

I am getting an array from response as below
items=[{
"displayName": "Adam Codo",
"postedTime": "2011-04-04T21:31:20.000Z",
"message" : "Hello Test Message"
},
{
"displayName": "Leena",
"postedTime": "2011-04-04T20:32:20.000Z",
"message" : " Start Hello Test Message"
},
{
"displayName": "Zohn",
"postedTime": "2011-04-03T22:47:20.000Z",
"message" : "Hi Leena"
},
{
"displayName": "Leena",
"postedTime": "2011-04-04T21:32:20.000Z",
"message" : " Start Hello Test Message"
},
{
"displayName": "Adam Codo",
"postedTime": "2011-04-04T22:13:10.000Z",
"message" : "Hello Test Message"
}]
I have so sort the array by the name & later by the time. so I need sorted array like below
items=[
{
"displayName": "Adam Codo",
"postedTime": "2011-04-04T22:13:10.000Z",
"message" : "Hello reply Test Message"
},
{
"displayName": "Adam Codo",
"postedTime": "2011-04-04T21:31:20.000Z",
"message" : "Hello Test Message"
},
{
"displayName": "Leena",
"postedTime": "2011-04-04T21:32:20.000Z",
"message" : " Start Hello Test Message"
},
{
"displayName": "Leena",
"postedTime": "2011-04-04T20:32:20.000Z",
"message" : " Start Hello Test Message"
},
{
"displayName": "Zohn",
"postedTime": "2011-04-03T22:47:20.000Z",
"message" : "Hi Leena"
}
]
Can anyone suggest me how to do this? Any idea would be great.
Do NOT use dictionaries
Build your own model instead and life will be easier.
Here's the model
struct Element {
let displayName: String
let postedTime: Date
let message: String
init?(dict:[String:String]) {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSXXXXX"
guard
let displayName = dict["displayName"],
let timeText = dict["postedTime"],
let postedTime = dateFormatter.date(from: timeText),
let message = dict["message"]
else { return nil }
self.displayName = displayName
self.postedTime = postedTime
self.message = message
}
}
Now let's make it Comparable
extension Element: Comparable {
static func <(lhs: Element, rhs: Element) -> Bool {
if lhs.displayName != rhs.displayName {
return lhs.displayName < rhs.displayName
}
return lhs.postedTime < rhs.postedTime
}
static func ==(lhs: Element, rhs: Element) -> Bool {
return lhs.displayName == rhs.displayName && lhs.postedTime < rhs.postedTime
}
}
Now given your array of dictionaries
let items = [
[
"displayName": "Adam Codo",
"postedTime": "2011-04-04T21:31:20.000Z",
"message" : "Hello Test Message"
],
[
"displayName": "Leena",
"postedTime": "2011-04-04T20:32:20.000Z",
"message" : " Start Hello Test Message"
],
[
"displayName": "Zohn",
"postedTime": "2011-04-03T22:47:20.000Z",
"message" : "Hi Leena"
],
[
"displayName": "Leena",
"postedTime": "2011-04-04T21:32:20.000Z",
"message" : " Start Hello Test Message"
],
[
"displayName": "Adam Codo",
"postedTime": "2011-04-04T22:13:10.000Z",
"message" : "Hello Test Message"
]
]
we can convert it to an array of Element(s) and finally sorting it
let sortedElms = items.flatMap(Element.init).sorted()
Result
[
Element(displayName: "Adam Codo", postedTime: 2011-04-04 21:31:20 +0000, message: "Hello Test Message"),
Element(displayName: "Adam Codo", postedTime: 2011-04-04 22:13:10 +0000, message: "Hello Test Message"),
Element(displayName: "Leena", postedTime: 2011-04-04 20:32:20 +0000, message: " Start Hello Test Message"),
Element(displayName: "Leena", postedTime: 2011-04-04 21:32:20 +0000, message: " Start Hello Test Message"),
Element(displayName: "Zohn", postedTime: 2011-04-03 22:47:20 +0000, message: "Hi Leena")
]
var sortedResults = items.sorted {
(dictOne, dictTwo) -> Bool in
if dictOne["displayName"]! != dictTwo["displayName"]! {
return dictOne["displayName"]! < dictTwo["displayName"]!
}
return dictOne["postedTime"]! < dictTwo["postedTime"]!
};
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc]
initWithKey: #"displayName" ascending: YES];
NSArray *sortedArray = [_locations sortedArrayUsingDescriptors:[NSArray arrayWithObject:sortDescriptor]];
NSArray *sortedLocations = [_locations sortedArrayUsingComparator: ^(NSDictionary *d1, NSDictionary *d2) {
ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate1 = [formatter dateFromString:[d1 valueForKey:#"postedTime"]];
NSDate *theDate2 = [formatter dateFromString:[d2 valueForKey:#"postedTime"]];
return [theDate1 compare:theDate2];
}];
OR
NSArray *sortedLocations = [_locations sortedArrayUsingComparator: ^(NSDictionary *d1, NSDictionary *d2) {
ISO8601DateFormatter *formatter = [[ISO8601DateFormatter alloc] init];
NSDate *theDate1 = [formatter dateFromString:[d1 valueForKey:#"postedTime"]];
NSDate *theDate2 = [formatter dateFromString:[d2 valueForKey:#"postedTime"]];
NSString *name1 = [d1 valueForKey:#"displayName"];
NSString *name2 = [d2 valueForKey:#"displayName"];
if ([name1 compare:name2]) {
return [theDate1 compare:theDate2];
}
return NSOrderedDescending;
}];
But be awere I did not check it

iphone map route issue

I am trying following code to get google maps api response
NSString* apiUrlStr = [NSString stringWithFormat:#"http://maps.googleapis.com/maps/api/directions/json?origin=%#&destination=%#&sensor=false", saddr, daddr];
NSURL* apiUrl = [NSURL URLWithString:apiUrlStr];
NSLog(#"api url: %#", apiUrl);
NSString *apiResponse = [NSString stringWithContentsOfURL:apiUrl encoding:NSStringEncodingConversionAllowLossy error:Nil];
I got this apiResponse json data from google api:
{
"routes" : [
{
"bounds" : {
"northeast" : {
"lat" : 23.0236292,
"lng" : 72.60381579999999
},
"southwest" : {
"lat" : 22.990296,
"lng" : 72.5293059
}
},
"copyrights" : "Map data ©2015 Google",
"legs" : [
{
"distance" : {
"text" : "10.8 km",
"value" : 10797
},
"duration" : {
"text" : "23 mins",
"value" : 1403
},
"end_address" : "35, Shivranjani, Jodhpur, Ahmedabad, Gujarat 380015, India",
"end_location" : {
"lat" : 23.0234672,
"lng" : 72.5293059
},
"start_address" : "6, Natvarlal Raval Marg, Archana Society, Bhairavnath, Maninagar, Ahmedabad, Gujarat 380008, India",
"start_location" : {
"lat" : 22.990296,
"lng" : 72.60381579999999
},
"steps" : [
{
"distance" : {
"text" : "0.9 km",
"value" : 898
},
"duration" : {
"text" : "2 mins",
"value" : 123
},
"end_location" : {
"lat" : 22.9943614,
"lng" : 72.5962808
},
"html_instructions" : "Head \u003cb\u003enorthwest\u003c/b\u003e on \u003cb\u003eNatvarlal Raval Marg\u003c/b\u003e toward \u003cb\u003eNatvarlal Raval Marg\u003c/b\u003e\u003cdiv style=\"font-size:0.9em\"\u003ePass by Nelsons International School (on the right)\u003c/div\u003e",
"polyline" : {
"points" : "khikC{lczLMBu#jBSd#}AtDg#hA_#z#o#rAYl#O\\yArCgA|BMXQ`#q#bBm#zAcAjCSf#kArCMZ"
},
"start_location" : {
"lat" : 22.990296,
"lng" : 72.60381579999999
},
"travel_mode" : "DRIVING"
},
{
"distance" : {
"text" : "0.2 km",
"value" : 192
},
"duration" : {
"text" : "1 min",
"value" : 40
},
I am using following code to get poly line points
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"points\":\\\"([^\\\"]*)\\\"" options:0 error:NULL];
NSTextCheckingResult *match = [regex firstMatchInString:apiResponse options:0 range:NSMakeRange(0, [apiResponse length])];
NSString *encodedPoints = [apiResponse substringWithRange:[match rangeAtIndex:1]];
return [self decodePolyLine:[encodedPoints mutableCopy]];
but it returns #"" for encodedPoints
is there any problem in regular expression ?
when you got the response in dictionary then do this,
NSMutableArray *pathArray = [NSMutableArray new];
NSArray *routes = [[directionResponse directionResponse] objectForKey:#"routes"];
NSDictionary *route = [routes lastObject];
DLog(#"Array routes :%#",routes);
if (route) {
NSString *overviewPolyline = [[route objectForKey: #"overview_polyline"] objectForKey:#"points"];
pathArray = [self decodePolyLine:overviewPolyline];
}
NSInteger numberOfSteps = pathArray.count;
CLLocationCoordinate2D coordinates[numberOfSteps];
for (NSInteger index = 0; index < numberOfSteps; index++)
{
CLLocation *location = [pathArray objectAtIndex:index];
CLLocationCoordinate2D coordinate = location.coordinate;
coordinates[index] = coordinate;
}
MKPolyline *polyLine = [MKPolyline polylineWithCoordinates:coordinates count:numberOfSteps];
I dont think you have to use regex for this, you could use a simple json parser in objetive c and access the poyline and its points, refer :- http://pivotallabs.com/parsing-json-in-objective-c/

Sort an array of objects by an objects value

I have an array of objects that I parse from a JSON. My JSON looks like this;
- message: [
-{
movie_id: 30,
movie_name: "Scream",
category_name: "Horror"
},
-{
movie_id: 31,
movie_name: "Avengers",
category_name: "Action"
},
-{
movie_id: 32,
movie_name: "Friday the 13th",
category_name: "Horror"
},
-{
movie_id: 33,
movie_name: "The ring",
category_name: "Horror"
},
-{
movie_id: 34,
movie_name: "Die Hard",
category_name: "Action"
},
-{
movie_id: 35,
movie_name: "The ring 2",
category_name: "Horror"
},
....
Its a JSON array of movies that contains many movies. What I am unable to do is parse each object and arrange them by category_name in an array, so all the "horror" will be grouped together, all the action, and all the romance etc etc. However...I need to be able to place a String value at the start of each category. So the array might look like this:
Index
0 "Horror"
1 Movie Object
2 Movie Object
3 Movie Object
4 "Romance"
5 Movie Object
6 Movie Object
7 "Action"
8 Movie Object
9 Movie Object
10 Movie Object
I have movie object with the following paramters;
NSString *movie_id
NSString * movie_name
NSString *category_name
Any help is greatly appreciated.
I would suggest a slightly different structure for the parsed data.
Rather than an array of mixed strings and objects, why not create a dictionary (using the category names as keys) of arrays? Just iterate through your original JSON. For each movie object, check to see if the key exists for that category name. If it does not, add a new array as the value for that category name. Then add the movie object to the array.
Your final dictionary would be something like this:
#{ #"Horror" : #[obj1, obj2, obj 3],
#"Romance" : #[obj4, obj5, obj 6],
#"Action" : #[obj7, obj8, obj 9] }
That way you can iterate through each category, and also iterate through the movies is each category
Suppose You have your array message then you can arrange them as
NSArray *categories = [message valueForKeyPath:#"#distinctUnionOfObjects.category_name"];
NSMutableArray *results = [NSMutableArray new];
for (NSString *categoryName in categories)
{
NSArray *groupArray = [message filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"category_name = %#", categoryName]];
[results addObject:categoryName];
[results addObjectsFromArray:groupArray];
}
and your final array I mean results will be
(
Horror,
{
"category_name" = Horror;
"movie_id" = 30;
"movie_name" = Scream;
},
{
" movie_name" = "Friday the 13th";
"category_name" = Horror;
"movie_id" = 32;
},
{
"category_name" = Horror;
"movie_id" = 33;
"movie_name" = "The ring";
},
{
"category_name" = Horror;
"movie_id" = 35;
"movie_name" = "The ring 2";
},
Action,
{
"category_name" = Action;
"movie_id" = 31;
"movie_name" = Avengers;
},
{
"category_name" = Action;
"movie_id" = 34;
"movie_name" = "Die Hard";
}
)
Hope this is what you want.
But this not a good coding practice, to have different data types(string and dictionary) in same array. so you should parse them like this
NSArray *categories = [message valueForKeyPath:#"#distinctUnionOfObjects.category_name"];
NSMutableDictionary *results = [NSMutableDictionary new];
for (NSString *categoryName in categories)
{
NSArray *groupArray = [message filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:#"category_name = %#", categoryName]];
[results setObject:groupArray forKey:categoryName];
}
and your result will be.
{
Action = (
{
"category_name" = Action;
"movie_id" = 31;
"movie_name" = Avengers;
},
{
"category_name" = Action;
"movie_id" = 34;
"movie_name" = "Die Hard";
}
);
Horror = (
{
"category_name" = Horror;
"movie_id" = 30;
"movie_name" = Scream;
},
{
" movie_name" = "Friday the 13th";
"category_name" = Horror;
"movie_id" = 32;
},
{
"category_name" = Horror;
"movie_id" = 33;
"movie_name" = "The ring";
},
{
"category_name" = Horror;
"movie_id" = 35;
"movie_name" = "The ring 2";
}
);
}
Now choose whatever you want.

Get NSArray/NSDictionary for Nested JSON

I have this JSON :
{
"_id" : "class_1",
"schedule" : [
{
"date" : "1-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Sports"
},
{
"time_range" : "10:00-12:00",
"subject" : "History"
}
]
},
{
"date" : "2-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Physics"
},
{
"time_range" : "10:00-12:00",
"subject" : "Chemistry"
},
{
"time_range" : "10:00-12:00",
"subject" : "Biology"
}
]
},
{
"date" : "3-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "English"
},
{
"time_range" : "10:00-12:00",
"subject" : "Maths"
}
]
},
{
"date" : "4-1-2014",
"subjects" : [
{
"time_range" : "08:00-10:00",
"subject" : "Spanish"
},
{
"time_range" : "10:00-12:00",
"subject" : "Choreography"
},
{
"time_range" : "12:00-14:00",
"subject" : "Music"
},
{
"time_range" : "14:00-16:00",
"subject" : "Sports"
},
{
"time_range" : "16:30-18:30",
"subject" : "Religion"
}
]
}
]
}
What I would like to do is get an NSArray/NSMutableArray or NSDictionary/NSMutableDictionary` with the subjects for a GIVEN date. So for example if I type in the date 4-1-2014, I would like to get an array or dictionary with the 5 subjects that are contained in that date.
What I would like to do is get an NSArray/NSMutableArray or NSDictionary/NSMutableDictionary with the subjects for a GIVEN date. So for example if I type in the date 1-1-2014, I would like to get an array or dictionary with the 2 subjects that are contained in that date.
This is what I have tried:
//NSDICTIONARY CONTAINING CLASS DATA FOR CLASS ID
NSDictionary *classData =
[NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingAllowFragments error:&error];
//NSMUTABLEDICTIONARY CONTAINING SCHEDULE DATA FOR CLASS ID
NSMutableArray *scheduleDatabyClassID = [classData objectForKey:#"schedule"];
//NSMUTABLEARRAY CONTAINING SCHEDULE SUBJECTS OF CLASS ID
NSMutableArray *subjectsDatabyDate =[[NSMutableArray alloc] init] ;
for (NSMutableDictionary *subjectsData in scheduleDatabyClassID ){
NSString *subjectsData_temp = [subjectsData objectForKey:#"subjects"];
NSString *schedule_date = [subjectsData objectForKey:#"date"];
NSString *check = #"25-11-2013";
if ([schedule_date isEqualToString:check]) {
[subjectsDatabyDate addObject:subjectsData_temp];
}
}
Below is what I would like to get, but WITHOUT MANUALLY setting the index to 0. I want subjectsDataByDate : for the value (1-1-2014) for example.
NSLog(#"subjectsDatabyDate \n %# ", [subjectsDatabyDate objectAtIndex:0]);
This did the trick. As I mentioned, I needed a function that returns me an NSArray with containing the GIVEN date:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"date==%#",#"1-1-2014"];
NSArray *result_wanted = [scheduleDatabyClassID filteredArrayUsingPredicate:predicate];
NSLog(#"THE RESULT \n %# ", result_wanted);
If you do this for many different dates, and repeatedly, I would proceed somehow different.
NSDictionary is a class for key-value pairs. Your whole JSON data is actually a dictionary with keys "_id" and "schedule", and "schedule" has an array value. But looking at the data, a dictionary would have been much more appropriate, with for example "1-1-2014" as key and the rest as data. So you could turn the whole array into a dictionary, similar to your own code:
NSMutableDictionary *subjectsDatabyDate =[NSMutableDictionary dictionary] ;
for (NSDictionary *subjectsData in scheduleDatabyClassID )
{
NSString *schedule_date = [subjectsData objectForKey:#"date"];
subjectsDatabyDate [schedule_date] = subjectsData;
}
Now you can access any date very quickly:
NSDictionary* result_wanted = subjectsDatabyDate [#"1-1-2014"];
The difference is that access to an NSDictionary uses a hash table that will go directly to the item that you want, while the "filteredArray" has to iterate through the whole array, every time you look for a date.

Resources