Change json format in NSDictionary (Objective C) - 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);

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

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
}

JSON string from NSMutableDictionary -

I wanted to generate a JSON string of the following format:
{
"test": {
"currency": "USD",
"gte": "100"
}
}
When I executed the following lines of code:
NSMutableArray *tempArray = [[NSMutableArray alloc] init];
[tempArray addObject:tempDict];
[tempArray addObject:subDict];
[dict setObject:tempArray forKey:#"test"];
I retrieved this JSON string.
{
"test": [{
"currency": "USD"
}, {
"gte": "100"
}]
}
Any idea where I'm going wrong?
You must do it like this instead:
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setObject: #"USD" forKey: #"Currency"];
[tempDict setObject: #"100" forKey: #"gte"];
[dict setObject:tempDict forKey:#"test"];
From your current try you are adding array of dictionary to dictionary so its display like
{"test":[{"currency":"USD"},{"gte":"100"}]}
You need to add dictionary,
Try Following,
NSDictionary * dict = [NSDictionary dictionaryWithObjectsAndKeys:
tempDict,
subDict,
nil];
NSDictionary *final=#{#"test": dict};
How about this?
NSMutableDictionary *dic = [#{} mutableCopy];
NSMutableDictionary *tempDic = [#{} mutableCopy];
tempDic[#"currency"] = #"USD";
tempDic[#"gte"] = #"100";
[dic setObject:dic forKey:#"test"];
Modern Objective-C style..
Try like this:-
NSDictionary *yourDict = #{#"test": #{#"currency": #"USD",#"gte": #"100"}};

How to parse JSON

How to parse this below "choices" on one array means when I have get "id" in array that all id values 108,109.... in 1st index in array but here is the 5 values in choices..so how to parse it
choices = (
{
id = 108;
label = Distributor;
},
{
id = 109;
label = "Clinical Lab";
},
{
id = 110;
label = Researcher;
},
{
id = 111;
label = "Current Customer";
},
{
id = 112;
label = "Past Customer";
}
);
Get in a single Step bro as
If your array is NSMutableArray then use as
NSArray *resultArray = [[NSArray arrayWithArray:temp] valueForKeyPath:#"id"]
If simple NSArray then use as
NSArray *resultArray = [jsonArray valueForKeyPath:#"id"]
You can do it using fast enumeration.
NSMutableArray *resultArray = [[NSMutableArray alloc] initWithCapacity:0];
// JSONDict is your JSON dict
for (NSDictionary *aDict in JSONDict[#"choices"]) {
[resultArray addObject:aDict[#"id"]];
}
NSLog(#"%#", resultArray);
Output:
(
108,
109,
110,
111,
112
)
If i understand your question properly, Then You can try this code for getting Ids in a Array:
NSMutableArray *arr = [[NSMutableArray alloc] init];
for (int i = 0;i<[choices count];i++)
{
[arr addObject:[[choices objectAtIndex:i] objectForKey:#"id"]];
}
NSLog(#"ID array : %#",arr);
[arr release];
try like this ,
NSMutableArray *idArray=[[NSMutableArray alloc]init];
for(int i=0;i<[jsonArray count];i++)
[idArray addObject:[[jsonArray objectAtIndex:i] valueForKey:#"id"]];
NSLog(#"%#",idArray);
here you'l get all the values in idArray.

NSArray and NSDictionary

I have NSDictionaries in NSArray just like below.
array(dictionary("user":1, "p1":1), dictionary("user":2, "p1":3),
dictionary("user":1, "p1":5), dictionary("user":2, "p1":7))
And I want to turn this array into dictionary like below.
NSArray *u1 = [NSArray arrayWithObjects:#"1", #"5", nil];
NSArray *u2 = [NSArray arrayWithObjects:#"3", #"7", nil];
keys = [NSArray arrayWithObjects:#"u1", #"u2", nil];
points = [NSDictionary dictionaryWithObjectsAndKeys:u1, #"u1", u2, #"u2", nil];
How can I do that? I am lost, can you guys please help me?
Couldn't you just iterate over your original array, asking each dictionary if the object for key "user" is 1, and if so, copy the object into a new array at index 0? Or if your user numbers are in counting order, maybe even have the index number equal the user number. Then repeat for "user" = 2, etc. Then make a dictionary so that each key/object pair is created by keys from the keys array (keys[i]) and objects from your new array (objects[i]).
What have you tried?
Here is some code typed directly into the answer, so it has not be tested:
You haven't given a name for your original array, so let's assume it is:
NSArray *originalArray;
We need a mutable dictionary to store the result:
NSMutableDictionary *points = [NSMutableDictionary new];
Now we need to process every element in the original array and it is a dictionary:
for(NSDictionary *item in originalArray)
{
Get the current entry in points array that matches item. You don't give types for your entries, so we'll use id:
id currentUser = [item objectForKey:#"user"];
NSMutableArray *currentValues = [points objectForKey:currentUser];
If this is the first occurrence of currentUser then currentValues will be nil, and we need to create an array for the p1 value and add it to points:
if (currentValues == nil)
[points addObject:[NSMutableArray arrayWithObject:[item objectForKey:#"p1"]
forKey:currentUser
]
]
Otherwise we just add the p1 value to the array:
else
[currentValues setObject:[item objectForKey:#"p1"]];
close out the loop and get the keys:
}
NSArray *keys = [points allKeys];
Now if you're using Xcode 4.5 you can use modern syntax for some of that:
NSMutableDictionary *points = [NSMutableDictionary new];
for(NSDictionary *item in originalArray)
{
id currentUser = item[#"user"];
NSMutableArray *currentValues = points[currentUser];
if (currentValues == nil)
points[currentUser] = [NSMutableArray arrayWithObject:item[#"p1"];
else
[currentValues addObject:item[#"p1"]];
}
NSArray *keys = [points allKeys];
HTH
Another possible solution (works with an arbitrary number of users):
NSArray *orig = #[
#{#"user" : #"1", #"p1" : #"1"},
#{#"user" : #"2", #"p1" : #"3"},
#{#"user" : #"1", #"p1" : #"5"},
#{#"user" : #"2", #"p1" : #"7"},
];
// Create set of all users (without duplicates)
NSSet *users = [NSSet setWithArray:[orig valueForKey:#"user"]];
NSMutableDictionary *points = [NSMutableDictionary dictionary];
for (NSString *user in users) {
// newKey = "u" + username, e.g. "u1" or "u2":
NSString *newKey = [#"u" stringByAppendingString:user];
// newValue = array of "p1" values of the current user:
NSPredicate *pred = [NSPredicate predicateWithFormat:#"user == %#", user];
NSArray *newValue = [[orig filteredArrayUsingPredicate:pred] valueForKey:#"p1"];
// Add to dictionary:
[points setObject:newValue forKey:newKey];
}
NSLog(#"%#", points);
Output:
{
u1 = (
1,
5
);
u2 = (
3,
7
);
}
And the keys can be obtained by
NSArray *keys = [points allKeys];
You can do, like this (code not tested)
NSMutableArray *keys=[NSMutableArray new];
NSMutableArray *u1=[NSMutableArray new];
NSMutableArray *u2=[NSMutableArray new];
NSMutableDictionary *points=[NSMutableDictionary new];
for (id dict in array){
NSString *user=[dict objectForKey:#"user"];
NSString *p1=[dict objectForKey:#"p1"];
[keys addObject:[NSString stringWithFormat:#"%#",user]];
if( [user isEqualToString:#"1"] ){
[u1 addObject:user];
}
else{
[u2 addObject:user];
}
}
points=[NSDictionary dictionaryWithObjectsAndKeys:u1,#"u1",u2, #"u2", nil];
Tons of approaches. Here's another:
NSArray *originalArray = #[
#{#"user":#"u1", #"p1":#"1"},
#{#"user":#"u2", #"p1":#"3"},
#{#"user":#"u1", #"p1":#"5"},
#{#"user":#"u2", #"p1":#"7"}
];
NSLog(#"originalArray = %#", originalArray);
NSMutableDictionary *results = [NSMutableDictionary dictionary];
for (NSDictionary *dictionary in originalArray) {
NSString *user = dictionary[#"user"];
NSString *p1 = dictionary[#"p1"];
if (!results[user])
results[user] = [NSMutableArray array];
[results[user] addObject:p1];
}
NSLog(#"results = %#", results);
That takes:
originalArray = (
{
p1 = 1;
user = u1;
},
{
p1 = 3;
user = u2;
},
{
p1 = 5;
user = u1;
},
{
p1 = 7;
user = u2;
}
)
And gives
results = {
u1 = (
1,
5
);
u2 = (
3,
7
);
}