Add dictionaries to nsdictionary as value for key - objective-c

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];

Related

How to format brackets of nested JSON

I'm trying to create a string which holds JSON data. I'm having an issue formatting the inner nested data, it currently has square brackets '[]' and I'm trying to change it to '{}', so it is valid JSON. Are there better approaches/solutions to parsing this data?
Actual Results:
[
[
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
],
[
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
]
]
Desired Results
[
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
},
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
}
]
Code
// Parse and loop through the JSON
for (NSDictionary * dataDict in eventArray) {
NSMutableArray *array = [[NSMutableArray alloc] init];
eventTime = [NSString stringWithFormat:#"%#%#",#"eventtime\":\"",[self eventTimeConversion:[dataDict objectForKey:#"event_time"]]];
keyID = [NSString stringWithFormat:#"%#%#",#"keyid\":\"",[dataDict objectForKey:#"key_id"]];
editTime = [NSString stringWithFormat:#"%#%#",#"edittime\":\"",[self eventTimeConversion:[dataDict objectForKey:#"event_time"]]];
projectID = [NSString stringWithFormat:#"%#%#",#"projectid\":\"",[gotHeaders objectAtIndex:0]];
lockID = [NSString stringWithFormat:#"%#%#",#"doorid\":\"",[dataDict objectForKey:#"lock_id"]];
eventType = [NSString stringWithFormat:#"%#%#",#"eventid\":\"",[dataDict objectForKey:#"event_type"]];
[array addObject:eventTime];
[array addObject:keyID];
[array addObject:editTime];
[array addObject:projectID];
[array addObject:lockID];
[array addObject:eventType];
[event_array addObject:array];
}
}
NSData *jsonnData = [NSJSONSerialization dataWithJSONObject:event_array options:NSJSONWritingPrettyPrinted error:&error];
NSString *eventsString = [[NSString alloc] initWithData:jsonnData encoding:NSUTF8StringEncoding];
Don't create a JSON string manually, create dictionaries, this is a simplified example for the keys eventtime and keyid
The code uses modern Objective-C syntax (introduced at least 6 years ago)
NSMutableArray *array = [[NSMutableArray alloc] init];
for (NSDictionary * dataDict in eventArray) {
NSString *eventTime = [self eventTimeConversion: dataDict[#"event_time"]];
NSString *keyID = dataDict[#"key_id"];
[array addObject:#{#"eventtime":eventTime, #"keyid":keyID}];
}
NSError *error;
NSData *jsonnData = [NSJSONSerialization dataWithJSONObject: array options:NSJSONWritingPrettyPrinted error:&error];
NSString *eventsString = [[NSString alloc] initWithData:jsonnData encoding:NSUTF8StringEncoding];
Instead of using an array to store the JSON id and value parameters, use a NSDictionary:
NSDictionary *d1 = [NSDictionary dictionaryWithObjectsAndKeys:
#"eventtime", #"2019-09-20 09:52:47",
#"keyid", #"15", nil];
[event_array addObject:d1];
...
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:event_array
options:NSJSONWritingPrettyPrinted error:&error];
NSString *eventsString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#", eventsString);
You will need to obviously replace the hardcoded values I have put on the dictionary in the example with your values.
This will output:
[
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
},
{
"eventtime":"2019-09-20 09:52:47",
"keyid":"15",
}
]

Unable to convert UTF-8 text from NSDictionary in Objective-C

Im using foursquare API to get some locations around me, but when the name of that place wasn't in english, the name will be like follows:
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
i tried to convert the response to a UTF-8 but nothing changed.
Here is my code:
-(void)setUpLocations{
NSURL *url = [NSURL URLWithString: #"https://api.foursquare...."];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Response: %#",[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"]);
}
And the log result is:
contact = {
};
id = 51712507498ec4e8c5ae9f48;
likes = {
count = 0;
groups = (
);
};
location = {
address = Abdoun;
cc = JO;
city = Amman;
country = Jordan;
distance = 3819;
lat = "31.95406043797281";
lng = "35.88095228186612";
};
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
restricted = 1;
stats = {
checkinsCount = 43;
tipCount = 2;
usersCount = 23;
};
verified = 0;
},
Any Suggestions ??
EDIT:
here is how i extract the data from the dictionary:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
namesArray = [[NSArray alloc]initWithArray:[self removeWhiteSpaces:[dic valueForKey:#"name"]]];
-(NSArray *)removeWhiteSpaces:(NSDictionary *)dic{
NSString *str = [NSString stringWithFormat:#"%#",dic];
NSString *str2 = [str stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *secondString = [str2 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *thirdString = [secondString stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *forthString = [thirdString stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *fifthString = [forthString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *items = [fifthString componentsSeparatedByString:#","];
return items;
}
And in the UITableView:
cell.textLabel.text = [NSString stringWithFormat:#"Name: %# ",[namesArray objectAtIndex:indexPath.row] ];
Update
After trying #Martin R answer i got the same results:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
NSString *value =[dic valueForKey:#"name"];
NSLog(#"%#", value);
UILabel *lbl = [[UILabel alloc]initWithFrame:self.view.frame];
lbl.numberOfLines = 0;
lbl.text = [NSString stringWithFormat:#"%#",value];;
[self.view addSubview:lbl];
and here is an image of the result
There is no problem.
NSLog() calls the description method of NSDictionary and NSArray, and that prints all non-ASCII characters as \Unnnn escape sequence.
If you extract the string values from the dictionary and print that you will see
that everything is correct.
Simple example:
NSDictionary *dict = #{ #"currency": #"€" };
NSLog(#"%#", dict);
// Output: { currency = "\U20ac"; }
NSString *value = dict[#"currency"];
NSLog(#"%#", value);
// Output: €
UPDATE: The problem seems to be in your removeWhiteSpaces: method, because
NSString *str = [NSString stringWithFormat:#"%#",dic];
already uses the description method to convert the dictionary to a string,
and the following stringByReplacingOccurrencesOfString calls are a (sorry!) very bad
method to fix that.
You should access the dictionary keys with objectForKey instead, or enumerate
the dictionary with for (NSString *key in dic) { ... } and build the desired
array.
UPDATE 2: From the JSON data (posted in chat discussion) it seem that you just need
NSArray *itemsArray = json[#"response"][#"groups"][0][#"items];
NSArray *namesArray = [itemsArray valueForKey:#"name"];
Note that "groups" is an array with one element.
Try to use this one..
[NSString stringWithUTF8String:]

How to generate a multi-line UILabel

I have a json call and I parse the results into a UILabel. In my json response I have a 4 Names under Clients.
I am trying to put all the Clients into my UILabel.
Currently I only see the last of the 4 clients from my json response but in my log I can see all 4 clients.
If you see the photo below you see brithouse which is the 4th client in the json call. I would like to view all 4 clients in mu uilabel? Currently I only see the last client.
Thanks
{
"ProfileID":34,
"ProfilePictureID":20,
"Name":"Bilbo Baggins",
"Clients":
[
{
"ClientID":91,
"Name":"Fnurky"
},
{
"ClientID":92,
"Name":"A different client"
},
{
"ClientID":95,
"Name":"Second Community"
},
{
"ClientID":96,
"Name":"Britehouse"
}
]
}
My objective C code
NSDictionary* json1 = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* latestLoans = [json1 objectForKey:#"Clients"]; //2
NSLog(#"Clients: %#", latestLoans); //3
NSArray *performersArray = [json1 objectForKey:#"Clients"];
for (NSDictionary *performerDic in performersArray) {
NSLog(#"%#", [performerDic objectForKey:#"Name"]);
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %# ",
[performerDic objectForKey:#"Name"]];
NSLOG
2013-05-16 13:03:52.820 com.barloworld.atajo[5137:907] Fnurky
2013-05-16 13:03:52.821 com.barloworld.atajo[5137:907] A different client
2013-05-16 13:03:52.821 com.barloworld.atajo[5137:907] Second Community
2013-05-16 13:03:52.822 com.barloworld.atajo[5137:907] Britehouse
Use this
NSDictionary* json1 = [NSJSONSerialization JSONObjectWithData:responseData //1
options:kNilOptions
error:&error];
NSArray* latestLoans = [json1 objectForKey:#"Clients"]; //2
NSArray *performersArray = [json1 objectForKey:#"Clients"];
NSMutableArray *array=[[NSMutableArray alloc]initWithCapacity:3];
for (NSDictionary *performerDic in performersArray) {
[array addObject:[performerDic objectForKey:#"Name"]];
}
NSString *output=[array componentsJoinedByString:#","];
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %# ",
output];
YOu can use this..
before the Loop:
NSString *tempString = #"";
In the Loop:
tempString = [tempString stringByAppendingFormat:#"%#", [performerDic objectForKey:#"Name"]];
After the Loop:
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %#", tempString];
This below of code will only add the last value into the label
jsonSummary.text = [NSString stringWithFormat:#"The clients under this user are: %# ",
[performerDic objectForKey:#"Name"]];
You have to APPEND each client name into string and then display the string value into the label... For appending into the string do,
JsonString =[NSString stringByAppendingFormat: [performerDic objectForKey:#"Name"]];
Now this string will have all Client values, Now
jsonSummary.text =[NSString stringWithFormat : #"YOUR OWN LINES %# " JsonString];

Iterate and map JSON dictionary to build array of objects - 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.

Pulling Data From JSON

I have a simple JSON string that looks like
(
{
ID = 1;
response = Yes;
}
)
And my NSDictionary is not pulling the objectForKey. The jsonArray is displaying correctly. My code:
hostStr = [[hostStr stringByAppendingString:post] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *hostURL = [NSURL URLWithString:hostStr];
NSString *jsonString = [[NSString alloc] initWithContentsOfURL:hostURL];
self.jsonArray = [jsonString JSONValue];
[jsonString release];
NSLog(#"%#", jsonArray);
NSDictionary *infoDictionary = [self.jsonArray objectForKey:#"ID"];
NSLog(infoDictionary);
This is probably the case since you have completely invalid JSON (test it out at http://jsonlint.com/). Because you are missing the quotation marks in your JSON the elements won't match the id ID. All object names/keys need to be in quotation marks.
You're lucky that your framework interprets your invalid JSON (somehow) correctly so that you actually get an array or a dictionary. Because of this the result of NSLog will be correct.
Rewrite your JSON like this to get it working:
{
"ID": 1,
"response": "YES"
}
(Also be sure that jsonArray is a NSDictionary)