Iterate and map JSON dictionary to build array of objects - Objective C - objective-c

I've got this response from JSOn web service:
categoria = (
{
"id_categoria" = 61;
imagen = "http://exular.es/mcommerce/image/data/ipod_classic_4.jpg";
nombre = Gorras;
},
{
"id_categoria" = 59;
imagen = "http://exular.es/mcommerce/image/data/ipod_touch_5.jpg";
nombre = Camisetas;
},
{
"id_categoria" = 60;
imagen = "http://exular.es/mcommerce/image/data/ipod_nano_1.jpg";
nombre = Pantalones;
}
);
}
It is feed in a dictionary in this piece of code:
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
//data =nil;
NSLog(#"JSNON %#", responseString);
NSDictionary *results = [responseString JSONValue];
NSLog(#"JSNON %#", results);
I need to iterate all the categories in the dictionary and create an NSArray that contains objects Categories with properties "name" and image".
Many thanks

NSArray *categories = [results objectForKey:#"categoria"];
This will create an array of your category objects. You can pass this array of dictionaries/objects to your custom object or just iterate through it pulling what you need.
Category *cat = [[Category alloc] initWithDictionary:[categories objectAtIndex:0]];
This is just assuming your init is set to handle a dictionary. There isn't enough code to know, but you should be able to figure it out from here.

Related

How to read individual values from JSON in NSDictionary

NSString *jsonString = #"{\"eventData\":{\"eventDate\":\"Jun 13, 2012 12:00:00 AM\",\"eventLocation\":{\"latitude\":43.93838383,\"longitude\":-3.46},\"text\":\"hkhkjh\",\"imageData\":\"\",\"imageFormat\":\"JPEG\",\"expirationTime\":1339538400000},\"type\":\"Culture\",\"title\":\"accIDENTE\"}";
NSData *jsonData1 = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *finalDictionary1 = [NSJSONSerialization JSONObjectWithData:jsonData1 options:NSJSONReadingAllowFragments error:nil];
NSLog(#"%#", finalDictionary1);
NSMutableArray *jsonParseArray = [[NSMutableArray alloc] initWithArray:[finalDictionary1 objectForKey:#"latitude"]];
NSDictionary *res = [jsonParseArray objectAtIndex:1];
NSLog(#"%#", res);
When I run this I get a bunch of errors. I want to get the value of latitude.
Your json don't have latitude key. See below.
{
eventData = {
eventDate = "Jun 13, 2012 12:00:00 AM";
eventLocation = {
latitude = "43.93838383";
longitude = "-3.46";
};
expirationTime = 1339538400000;
imageData = "";
imageFormat = JPEG;
text = hkhkjh;
};
title = accIDENTE;
type = Culture;
}
=> New array with empty object.
NSMutableArray *jsonParseArray = [[NSMutableArray alloc] initWithArray:[finalDictionary1 objectForKey:#"latitude"]];
and you try with none exist element.
NSDictionary *res = [jsonParseArray objectAtIndex:1];
See your json: latitude is not an array. And it's child element of eventLocation. Try to get eventLocation as Dictionary first then get latitude via eventLocation.
Hop this helps!
This code will get the latitude from data.
NSString *jsonString = #"{\"eventData\":{\"eventDate\":\"Jun 13, 2012 12:00:00 AM\",\"eventLocation\":{\"latitude\":43.93838383,\"longitude\":-3.46},\"text\":\"hkhkjh\",\"imageData\":\"\",\"imageFormat\":\"JPEG\",\"expirationTime\":1339538400000},\"type\":\"Culture\",\"title\":\"accIDENTE\"}";
NSData *jsonData1 = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *finalDictionary1 = [NSJSONSerialization JSONObjectWithData:jsonData1 options:NSJSONReadingAllowFragments error:nil];
NSLog(#"%#", finalDictionary1);
NSString *latitute = finalDictionary1[#"eventData"][#"eventLocation"][#"latitude"];
NSLog(#"%#", latitute);
Although in a real world example were your JSON might come from a server, you will probably want to add error handling, indexing the data in multiple steps assuring the keys exists and values are of the expected type.

Updating key in NSMutableDictionary

json is a NSMutableDictionary with a key "message". I need to "clean" the data in that key using stringByReplacingOccurrencesOfString
NSLog(#"json: %#", json); outputs this:
json: {
conversationId = 61;
countmessagesinconversation = 2;
message = "Messages exist!";
messagesinconversation = (
{
message = "Hi";
messagecreated = "June 24, 2013 16:16";
messageid = 68;
sentby = Thomas;
sentbyID = 1;
title = "Subject";
},
{
message = "What's up?";
messagecreated = "September 22, 2013 17:00";
messageid = 331;
sentby = Steve;
sentbyID = 2;
title = "Subject";
}
);
success = 1;
}
So, this is what I've come up with, but I'm clearly getting it all wrong.
NSString *newstr = [[NSString alloc]init];
for (newstr in [[[json objectForKey:#"messagesinconversation"]allKeys]copy]){
newstr = [newstr stringByReplacingOccurrencesOfString:#" "
withString:#""];
[json setValue:newstr forKey:#"message"];
}
Could somebody please help me out with this and explain so I understand the concept? I know how to do this with an array but what my problem is (I think) is that I do not fully understand how to access the right key in the dictionary.
Edit: Sorry for not being clear in my question. What happens is that if there are two space characters in the key message then " " shows up when I display it on the screen.
//First get the array of message dictionaries:
NSArray * messages = [json objectForKey:#"messagesinconversation"];
//create new array for new messages
NSMutableArray * newMessages = [NSMutableArray arrayWithCapacity:messages.count];
//then iterate over all messages (they seem to be dictionaries)
for (NSDictionary * dict in messages)
{
//create new mutable dictionary
NSMutableDictionary * replacementDict = [NSMutableDictionary dictionaryWithDictionary:dict];
//get the original text
NSString * msg = [dict objectForKey:#"message"];
//replace it as you see fit
[replacementDict setObject:[msg stringByReplacingOccurrencesOfString:#" " withString:#""] forKey:#"message"];
//store the new dict in new array
[newMessages addObject:replacementDict];
}
//you are done - replace the messages in the original json dict
[json setObject:newMessages forKey:#"messagesinconversation"];
Add your array of dictionary in another mutable array
NSMutableArray *msgArray = [[json objectForKey:#"messagesinconversation"] mutableCopy];
Use for loop for access it.
for (int i = 0 ; i < msgArray.count ; i++)
{
[[[msgArray objectAtindex:i] objectForKey:#"message"] stringByReplacingOccurrencesOfString:#" " withString:#""];
}
[self.mainJSONDic setValue:msgArray forKey:#"messagesinconversation"];
Try this code might helpful in your case:
Now that the requirements are more clear I'll try an answer. I try to use the same names as in your question and suggested in erlier answers.
Make json an NSMUtableDictionary where you declare it. Then go forward:
json = [json mutableCopy]; // creates a mutable dictionary based on json which is immutable as result of the json serialization although declared as mutable.
NSMutableArray *msgArray = [[json objectForKey:#"messagesinconversation"] mutableCopy]; //this fetches the array from the dictinary and creates a mutable copy of it.
[json setValue:newstr forKey:#"messagesinconversation"]; // replace the original immutable with the mutable copy.
for (int i = 0; i < [msgArray count]; i++) {
NSMutableDictionary mutableInnerDict = [[msgArray objectAtIndex:i] mutableCopy]; // fetching the i-th element and replace it by a mutable copy of the dictionary within.
[msgArray replaceObjectAtIndex:i withObject:mutableInnerDict]; // it is now mutable and replaced within the array.
NSString *newString = [[[msgArray objectAtindex:i] objectForKey:#"message"] stringByReplacingOccurrencesOfString:#" " withString:#" "]; // crates a new string with all &nbsp removed with blanks.
[mutableInnerDict setValue:newString forKey:#"message"];
}
Regarding the replacement of &nbsp with " ", is this really what you want? I am asking because &nbsp does not occur in your sample data. Or do you want to remove blanks at all?

Not able to save multiple objects using nskeyedArcheiver

I am trying to use NsKeyedArchiever to take save Car details which contains model,make,year,color,vin.
The code for this is as follows :
void CarData()
{
Car *myCar = [[Car alloc] init];
myCar.model = [carTempArray objectAtIndex:0];//Temporary array contains value
myCar.make = [carTempArray objectAtIndex:1];
myCar.color = [carTempArray objectAtIndex:2];
myCar.year = [carTempArray objectAtIndex:3];
myCar.vin = [NSNumber numberWithInt:check];
NSString *docspath = [NSHomeDirectory() stringByAppendingPathComponent:#"documents"];
BOOL saved =[NSKeyedArchiver archiveRootObject: myCar toFile:docspath];
NSLog(#"did save state %d",saved);
[myCar release];
[NSKeyedArchiver release];
}
And after that using NSkeyedUnarcheiver as follows :
void ShowData()
{
NSString *docspath = [NSHomeDirectory() stringByAppendingPathComponent:#"documents"];
Car * retrieveCar = [NSKeyedUnarchiver unarchiveObjectWithFile:docspath];
// for(int i=0 ; i<studentList.count;i++)
{
// Car * retrieveCar =[studentList objectAtIndex:0];
NSString * first = retrieveCar.model;
NSString * first1 = retrieveCar.make;
NSString * first2 = retrieveCar.color;
NSString * first3 = retrieveCar.year;
NSLog(#"%#",first );
NSLog(#"%#",first1 );
NSLog(#"%#",first2 );
NSLog(#"%#",first3 );
}
But this only takes one value and uses one value.I want to save the NSKeyedArchiever object in an array so that multiple cars can be a part of it using same code.And Load the same as above.Please rectify the problem .I want to run the code for multiple cars and i am able to perform the following tasks in array of cars as searching a car,deleting a car record and adding a car.

Add dictionaries to nsdictionary as value for key

I have to prepare a dictionary for serialization and then post it to server. Dictionary may have several other dictionaries as values for #"items" key. But some brackets interrupt. And server response me an error html.
NSMutableArray *a = [[NSMutableArray alloc]init];
for(int i = 0; i < [self.cartCopy count]; i++) {
NSString *itemNumber = [NSString stringWithFormat:#"%d", i + 1];
NSDictionary *tempDict = #{ itemNumber : #{
#"item_id" : [[self.cartCopy objectAtIndex:i]objectForKey:#"id"],
#"quantity" : [[self.cartCopy objectAtIndex:i]objectForKey:#"quantity"],
#"type" : [[self.cartCopy objectAtIndex:i]objectForKey:#"type"],
#"color_id" : #"0",
}
};
[a addObject:tempDict];
}
NSDictionary *dict = #{
#"date":oDate,
#"address":oAddress,
#"name":oName,
#"shipping_date":oShippingDate,
#"receiver_phone":oReceiverPhone,
#"customer_phone":oCustomerPhone,
#"total_price": oTotalPrice ,
#"additional_info": #"asd",
#"items": a
};
UPDATE: My NSLog of string after [NSJSONSerialization dataWithJSONObject:dict options:kNilOptions error:nil] :
{"address":"asd",
"name":"asd",
"receiver_phone":"123",
"customer_phone":"123",
"total_price":"1",
"date":"2013-03-05 21:22:55",
"additional_info":"asd",
"items":[
{"1":{
"type":"2",
"color_id":"0",
"item_id":10,
"quantity":"3"
}
},
{"2":{
"type":"1",
"color_id":"0",
"item_id":74,
"quantity":"3"
}
}
],
"shipping_date":"2030-03-03 12:12:12"
}
I think the reason is square brackets. How can i delete them?
For example, it works perfectly with dictionary:
NSDictionary *dict = #{
#"date":oDate,
#"address":oAddress,
#"name":oName,
#"shipping_date":oShippingDate,
#"receiver_phone":oReceiverPhone,
#"customer_phone":oCustomerPhone,
#"total_price": oTotalPrice ,
#"additional_info": #"asd",
#"items": #{
#"1":#{
#"type":#"1",
#"color_id":#"0",
#"item_id":#"1",
#"quantity":#"1"
},
#"2":#{
#"type":#"1",
#"color_id":#"0",
#"item_id":#"1",
#"quantity":#"1"
}
}
};
In your example that works perfectly the items object is a dictionary with keys {1, 2}.
In your output JSON your items object is an array.
This array contains 2 objects, each one is a dictionary.
The first contains a single key {1}.
The second contains a single key {2}.
You just need to remove the array and use a dictionary instead to store these dictionaries.
That looks as if you want to send JSON to the server. You can create JSON data from your dictionary with
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:&error];
If you need it as a string:
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

objective-c: read an array create by json

I begin in Ios dev and I got some troubles to manipulate an array create by Json :
I call in my app a web Service which return me data :
{evenements =(
({
dateEvenement ={
1 = "01-01-2013";
2 = "02-01-2013";
3 = "03-01-2013";
4 = "04-01-2013";
};
idEvenement = 61;
nbrInvite = 1;
nomEvenement = "My event Name";
nomUtilisateur = "Lucas ";
}
),
);
}
I'm able to get all the values by the following code except for "dateEvenement" :
NSArray *msgList;
msgList = [ jsonResults objectForKey:#"evenements" ];
for (NSDictionary *evenements in msgList) {
for (NSDictionary *evenement in evenements ) {
NSString *idEvenement = [evenement objectForKey:#"idEvenement"];
NSString *nomUtilisateur = [evenement objectForKey:#"nomUtilisateur"];
NSString *nomEvenement = [evenement objectForKey:#"nomEvenement"];
NSString *nbrInvite = [evenement objectForKey:#"nbrInvite"];
NSArray *dates = [ evenement objectForKey:#"dateEvenement" ];
}
}
Can you help me for getting datas of "dateEvenement"
Well in your JSON the dateEvenement isn't an Array but a dictionary:
NSDictionary *dates = [ evenement objectForKey:#"dateEvenement"];
for(NSNumber *key in dates) {
NSString *dateString = [dates objectForKey:key];
NSLog(%# : %#, key, dateString);
}
As declared in your JSON example the key's for the dictionary are numbers, thus you should NSNumber object for the key type.