How to format brackets of nested JSON - objective-c

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",
}
]

Related

create a dictionary with an array of dictionaries

Noob here. I recently started working with objective C, and currently I am stuck with dictionary concept. I want to create a json object as shown below:
{"UserData": {
"Name": Mike Smith,
"Age": 32,
"category": [1,2,3],
"Weekly Data": [
{"Monday" : [1.0,2.0,3.0]},
{"Tuesday": [1.0,2.0,3.0]}
]
}
}
I wrote the following piece of code which doesn't give the desired result. I wonder if someone could help me.
-(NSString*)populateUserPreferences
{
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
NSMutableArray *categorydata = [[NSMutableArray alloc] init];
NSMutableArray *weeklydata = [[NSMutableArray alloc] init];
for (int i=0;i<4; i++)
{
[categorydata addObject:[NSNumber numberWithInt:i]];
}
NSMutableArray *mondaydata = [[NSMutableArray alloc] init];
for (int j=0; j<3; j++)
{
[mondaydata addObject:[NSNumber numberWithInt:j]];
}
NSMutableArray *tuesdaydata = [[NSMutableArray alloc] init];
for (int j=0; j<3; j++)
{
[tuesdaydata addObject:[NSNumber numberWithInt:j]];
}
NSDictionary *monday = [NSDictionary dictionaryWithObject:mondaydata];
NSDictionary *tuesday = [NSDictionary dictionaryWithObject:tuesdaydata];
[weeklydata addObject: monday ];
[weeklydata addObject: tuesday ];
}
[dict setObject:[NSString stringWithFormat:"Mike Smith"] forKey:#"Name"];
[dict setObject:[NSNumber numberWithInteger:32.0] forKey:#"Age"];
[dict setObject:categorydata forKey:#"category"];
[dict setObject:weeklydata forKey:#"Weekly Data"];
NSString * userdata = [dict JSONRepresentation];
NSLog(request);
NSDictionary *userdataJson = [NSDictionary dictionaryWithObject:dict forKey:#"userData"];
return [userdataJson JSONRepresentation];
}
Thanks in advance for looking into it.
Apoorva
The mistake is when creating the monday and tuesday dictionary.
// mondaydata & tuesday is just array.
NSDictionary *monday = [NSDictionary dictionaryWithObject:mondaydata];
NSDictionary *tuesday = [NSDictionary dictionaryWithObject:tuesdaydata];
This code is mistake since you did not assign the dictionary properly (where is the key for the dictionary?). Instead you should do:
NSDictionary *mondayDict = [[NSDictionary alloc] init];
[mondayDict setObject:mondaydata forKey:"Monday"];
NSDictionary *tuesdayDict = [[NSDictionary alloc] init];
[tuesdayDict setObject:tuesdaydata forKey:"Tuesday"];
Then you can add mondayDict and tuesdayDict to your array weeklydata.
ps. just a note, name your variable meaningfully. For example, mondaydata is not descriptive enough. You should use mondayArr for example. To easily identify it is an array. Just a normal coding practice to share.
NSDictionary * dict = #{#"UserData": #{
#"Name": #"Mike Smith",
#"Age": #32,
#"category": #[#1,#2,#3],
#"Weekly Data": #[
#{#"Monday" : #[#1.0,#2.0,#3.0]},
#{#"Tuesday": #[#1.0,#2.0,#3.0]}
]
}
};
NSError * error = nil;
NSData * data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
if (error) {
NSLog(#"%#", [error localizedDescription]);
} else {
// Do what you want
}

Objective C NSDictionary JSON in One line

i'm working on one objective C application where i'm taking JSON data and i need to insert this data(date) inside Dictionary fillDefaultColors. My fillDefaultColors should be in format like this:
self.fillDefaultColors = #{ #"2017/06/18":greenColor,
#"2017/06/19":orangeColor,
#"2017/06/20":greenColor,
...
};
but when i print in console log they are each in separate row and in application i can see colour just for last item from JSON
2017-06-19 15:30:12.310 CalendarTest[1905:364525] {
"2017/06/20" = "greenColor";
}
2017-06-19 15:30:12.311 CalendarTest[1905:364525] {
"2017/06/18" = "orangeColor";
}
So in application i see background for last date in console 2017/06/18
Here is my code
NSError *error = nil;
NSURL *url = [NSURL URLWithString: #"http://..."];
NSData *data = [NSData dataWithContentsOfURL:url options:NSDataReadingUncached error:&error];
if(!error)
{
NSDictionary* json = [NSJSONSerialization
JSONObjectWithData:data
options:NSJSONReadingMutableContainers
error:&error];
NSMutableArray *array= [json objectForKey:#"horses"];
for(int i=0; i< array.count; i++)
{
NSDictionary *horsedata = [array objectAtIndex:i];
NSString *date = [horsedata objectForKey:#"date"];
NSNumber *averagetemp = [horsedata objectForKey:#"averagetemperature"];
if([averagetemp isEqual:#(28)]) {tempColor = greenColor;} else {
tempColor = orangeColor;
}
self.fillDefaultColors = #{date: tempColor};
NSLog(#"%#", _fillDefaultColors);
}
}
JSON: {"horses":[{"id":1,"name":"Horse","date":"2017/06/17","averagetemperature":28},{"id":1,"name":"Horse","date":"2017/06/18","averagetemperature":25}]}
Thanks
it s because you are allocating a new dictionary in each iteration:
self.fillDefaultColors = #{date: tempColor};
you need to append instead:
NSMutableArray *array= [json objectForKey:#"horses"];
self.fillDefaultColors = [[NSMutableDictionary alloc]init];
for(int i=0; i< array.count; i++)
{
NSDictionary *horsedata = [array objectAtIndex:i];
NSString *date = [horsedata objectForKey:#"date"];
NSNumber *averagetemp = [horsedata objectForKey:#"averagetemperature"];
if([averagetemp isEqual:#(28)]) {tempColor = greenColor;} else {
tempColor = orangeColor;
}
[self.fillDefaultColors setObject:tempColor forKey:date];
NSLog(#"%#", _fillDefaultColors);
}
This is the same solution as in Hussein's answer but with Modern Objective-C Syntax – which has been introduced at least 5 years ago.
NSArray *horses = json[#"horses"];
self.fillDefaultColors = [[NSMutableDictionary alloc] init];
for (NSDictionary *horsedata in horses)
{
NSString *date = horsedata[#"date"];
NSNumber *averagetemp = horsedata[#"averagetemperature"];
self.fillDefaultColors[date] = (averagetemp.integerValue == 28) ? greenColor : orangeColor;
NSLog(#"%#", _fillDefaultColors);
}

Change json format in NSDictionary (Objective C)

I am new in ios programming. I should apply data to the chart. But the framework(ShinobiControls) which I use accepts only json with certain format. So I have to change my json data format to appropriate. I have NSDictionary which contain json like this:
"data": [
"01.01.2015",
"01.01.2015",
"01.01.2015",
"01.01.2015"]
"close": [
[
1,
1,
1,
1]
And now I should change format of the json like this:
[
{
"date": "01.01.2015",
"close": 1
},
{
"date": "01.01.2015",
"close": 1
},
{
"date": "01.01.2015",
"close": 1
},
{
"date": "01.01.2015",
"close": 1
}
]
I did some manipulation with converting NSDictionary to NSArray, but didn't get anything. How can I do it? Do you have any ideas? Thank you.
So if i understand your question right, you have a dictionary that contains 2 arrays and you want to convert it to an array that contains dictionaries , assuming that that the count of the arrays in the dictionary is equal, you can do the following
//This is the first array in your dictionary
NSArray * dataArr = [data objectForKey:#"data"] ;
//This the second array in your dictionary
NSArray * closeArr = [data objectForKey:#"close"] ;
NSUInteger dataCount = [dataArr count] ;
NSUInteger closeCount = [closeArr count] ;
//This will be your result array
NSMutableArray * newData = [NSMutableArray new] ;
//The loop condition checks that the current index is less than both the arrays
for(int i = 0 ; i<dataCount && i<closeCount ; i++)
{
NSMutableDictionary * temp = [NSMutableDictionary new] ;
NSString * dataString = [dataArr objectAtIndex:i];
NSString * closeString = [closeArr objectAtIndex:i];
[temp setObject:dataString forKey:#"date"];
[temp setObject:closeString forKey:#"close"] ;
[newData addObject:temp];
}
NSArray *Arr = [[NSArray alloc] initWithObjects:#"01.01.2015",#"01.01.2015",#"01.01.2015",#"02.01.2015", nil];
NSArray *Arr1 = [[NSArray alloc] initWithObjects:#"1",#"1",#"1",#"1", nil];
NSDictionary *Dic = [[NSDictionary alloc] initWithObjectsAndKeys:Arr,#"data",Arr1,#"close", nil];
NSLog(#"%#",Dic);
NSMutableArray *ArrM = [[NSMutableArray alloc] init];
for ( int i = 0; i<Arr.count; i++) {
NSDictionary *Dic = [[NSDictionary alloc] initWithObjectsAndKeys:Arr[i],#"data",Arr1[i],#"close", nil];
[ArrM addObject:Dic];
}
NSLog(#"%#",ArrM);
NSError * err;
NSData * jsonData = [NSJSONSerialization dataWithJSONObject:ArrM options:0 error:&err];
NSString * myString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"%#",myString);

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

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