How can i create NSDictionary with multiple array of key and value - ios

i tried to create static JSONArray of value in IOS using Objective -c
i want like this
tabledata={
["name":"image 1","path":"img1.jpg"],
["name":"image 2","path":"img2.jpg"],
["name":"image 3","path":"img3.jpg"],
["name":"image 4","path":"img4.jpg"],
["name":"image 5","path":"img5.jpg"],
["name":"image 6","path":"img6.jpg"],
["name":"image 7","path":"img7.jpg"]}
this is my data.. please help me any one how can i declare in objective-c..

You can create dictionary like below
NSDictionary *dict = #{
#"array": #[
#{
#"name":#"image 1",
#"path":#"img1.jpg"
},
#{
#"name":#"image 2",
#"path":#"img2.jpg"
}
....
]
};
and Array
NSArray *array = #[
#{
#"name":#"image 1",
#"path":#"img1.jpg"
},
#{
#"name":#"image 2",
#"path":#"img2.jpg"
}
....
];
For get value from NSDictionary
NSArray *array = NSDictionary[#"array"]
NSDictionary *firstObj = array[0];
NSString *name = firstObj[#"name"]
NSString *path = firstObj[#"path"]
from Array just
NSDictionary *firstObj = array[0];
NSString *name = firstObj[#"name"]
NSString *path = firstObj[#"path"]

One of the alternative old approach is:
NSMutableArray *tableData = [[NSMutableArray alloc] init];
NSMutableDictionary * dict1 = [[NSMutableDictionary alloc] init];
[dict1 setValue:#"image 1" forKey:#"name"];
[dict1 setValue:#"img1.jpg" forKey:#"path"];
NSMutableDictionary * dict2 = [[NSMutableDictionary alloc] init];
[dict2 setValue:#"image 2" forKey:#"name"];
[dict2 setValue:#"img2.jpg" forKey:#"path"];
NSMutableDictionary * dict3 = [[NSMutableDictionary alloc] init];
[dict3 setValue:#"image 3" forKey:#"name"];
[dict3 setValue:#"img3.jpg" forKey:#"path"];
[tableData addObject:dict1];
[tableData addObject:dict2];
[tableData addObject:dict3];
NSLog(#"%#",tableData);
//To Fetch Values
NSDictionary *dictionary1 = [tableData objectAtIndex:0];
NSLog(#"%#", [dictionary1 valueForKey:#"name"]);

You can make JsonString to NSDicitonary.
NSError *jsonError;
NSData *objectData = [#"{\"2\":\"3\"}" dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:objectData
options:NSJSONReadingMutableContainers
error:&jsonError];
and It is make NSDictionary with array.
- (NSDictionary *) indexKeyedDictionaryFromArray:(NSArray *)array
{
id objectInstance;
NSUInteger indexKey = 0U;
NSMutableDictionary *mutableDictionary = [[NSMutableDictionary alloc] init];
for (objectInstance in array)
[mutableDictionary setObject:objectInstance forKey:[NSNumber numberWithUnsignedInt:indexKey++]];
return (NSDictionary *)[mutableDictionary autorelease];
}

Related

Creating NSDictionary

how i can create Dictionary that when i create jsondata with it, json looks like :
"historyStep":[
{
"counter": "50",
"timestamp": "1461674383632"
}
]
I did this :
NSMutableDictionary*jsonDictOth = [[NSMutableDictionary alloc]init];
[jsonDictOth setObject:#(810) forKey:#"counter"];
[jsonDictOth setObject:#"1464957395241.447998" forKey:#"timestamp"];
NSMutableDictionary *jsonDictMain = [[NSMutableDictionary alloc]initWithObjectsAndKeys:jsonDictOth,#"historyStep", nil];
NSError*error;
NSData *data = [NSJSONSerialization dataWithJSONObject:jsonDictMain
options:NSJSONWritingPrettyPrinted
error:&error];
but it looks :
historyStep = {
counter = 810;
timestamp = "1464957395241.447998";
};
You are missing a level: NSDictionary (top level) with NSArray of NSDictionary in the top level key historyStep:
NSMutableDictionary *topLevel = [[NSMutableDictionary alloc] init];
NSArray *historySteps = [[NSMutableArray alloc] init];
//Here you may have a for loop in case there are more steps
NSDictionary *aStep = #{#"counter":#"50", #"timestamp":#"1461674383632"};
[historySteps addObject:aStep]
[topLevel setObject:historySteps forKey#"historyStep"];
NSError*error;
NSData *data = [NSJSONSerialization dataWithJSONObject:topLevel
options:NSJSONWritingPrettyPrinted
error:&error];
NSDictionary *innerDictionary = [[NSDictionary alloc]initWithObjectsAndKeys:#"50", #"counter",#"1461674383632", #"timestamp", nil];
NSArray *array = [[NSArray alloc]initWithObjects:innerDictionary, nil];
NSDictionary *outerDict = [[NSDictionary alloc]initWithObjectsAndKeys:array, #"historyStep", nil];
Use this code it will work perfectly.
Your code should be like,
NSMutableDictionary*jsonDictOth = [[NSMutableDictionary alloc]init];
[jsonDictOth setObject:#(810) forKey:#"counter"];
[jsonDictOth setObject:#"1464957395241.447998" forKey:#"timestamp"];
NSMutableArray *arr = [[NSMutableArray alloc]init];
[arr addObject:jsonDictOth];
NSMutableDictionary *jsonDictMain = [[NSMutableDictionary alloc]initWithObjectsAndKeys:arr,#"historyStep", nil];
NSLog(#"jsonMain is %#",jsonDictMain);
NSError*error;
NSData *data = [NSJSONSerialization dataWithJSONObject:jsonDictMain
options:0
error:&error];
It's output is,
jsonMain is {
historyStep = (
{
counter = 810;
timestamp = "1464957395241.447998";
}
);
}
You just missed one array between

Mutable array only contains identical items

I am trying to store Json data to a mutable array. The JSON data has "city" and main dictionary branch inside a loop , where main branch contains temperature. When I loop through the main, all the previous temperatures are replaced by the later.
Here's the sample code :
object = [[NSMutableArray alloc]init];
NSURL *url = [NSURL URLWithString:#"http://api.openweathermap.org/data/2.5/forecast/city?q=london,uk&APPID="];
//8a7bc4e5d8246122294adb174b708711
NSData *data = [NSData dataWithContentsOfURL:url];
Model *mod = [[Model alloc]init];
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&error];
NSDictionary *cityDict = [jsonDict objectForKey:#"city"];
NSString *cityName = [cityDict objectForKey:#"name"];
// NSLog(#"%#",cityName);
NSLog(#"%#",mod.city);
NSMutableArray *arrayOfTemperature = [jsonDict objectForKey:#"list"];
for (NSDictionary *obj in arrayOfTemperature) {
NSDictionary *main = [obj objectForKey:#"main"];
NSString *temp = [main objectForKey:#"temp"];
//NSLog(#"%#",temp);
mod.temp = temp;
[object addObject:mod];
}
You are reusing the same mod instance over and over. You need to create a new one each iteration.
Move the line:
Model *mod = [[Model alloc]init];
to inside the for loop:
NSMutableArray *arrayOfTemperature = [jsonDict objectForKey:#"list"];
for (NSDictionary *obj in arrayOfTemperature) {
Model *mod = [[Model alloc]init];
NSDictionary *main = [obj objectForKey:#"main"];
NSString *temp = [main objectForKey:#"temp"];
//NSLog(#"%#",temp);
mod.temp = temp;
[object addObject:mod];
}

Sort array with dictionaries by date

I have an NSArray with NSDictionary inside. It looks like:
etc.
I need to sort it by date inside NSDictionary. I need something like this:
How can I do this? Here is my method which gives me first unsorted array:
- (void)iterateOverDocumentsDirectory
{
arrayWithFiles = [NSMutableArray new];
NSFileManager *fileManager = [[NSFileManager alloc] init];
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirPath = [paths objectAtIndex:0];
NSString *finalPathToFolder = [NSString stringWithFormat:#"%#/", documentsDirPath];
albumNames = [[fileManager contentsOfDirectoryAtPath:finalPathToFolder error:&error] mutableCopy];
if (albumNames == nil) {
// error...
}
for (NSString *album in albumNames)
{
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:album forKey:#"name"];
NSString *finalPathToFiles = [NSString stringWithFormat:#"%#/%#", documentsDirPath, album];
NSArray *tempArray = [fileManager contentsOfDirectoryAtPath:finalPathToFiles error:&error];
NSMutableArray *arrayWithEachFiles = [NSMutableArray new];
for (NSString *tempString in tempArray)
{
NSMutableDictionary *eachFileDict = [[NSMutableDictionary alloc] init];
NSString *pathToFile = [NSString stringWithFormat:#"%#/%#/%#", documentsDirPath, album, tempString];
[eachFileDict setValue:pathToFile forKey:#"path"];
NSDictionary *filePathsArray1 = [[NSFileManager defaultManager] attributesOfItemAtPath:pathToFile error:nil];
NSDate *modifiedDate = [filePathsArray1 objectForKey:NSFileCreationDate];
[eachFileDict setValue:modifiedDate forKey:#"date"];
[arrayWithEachFiles addObject:eachFileDict];
}
NSSortDescriptor *ageDescriptor = [[NSSortDescriptor alloc] initWithKey:#"date" ascending:YES];
NSArray *sortDescriptors = #[ageDescriptor];
NSArray *sortedArrayWithFiles = [[arrayWithEachFiles sortedArrayUsingDescriptors:sortDescriptors] mutableCopy];
[tempDict setValue:sortedArrayWithFiles forKey:#"files"];
[arrayWithFiles addObject:tempDict];
}
}
Use following code for sorting the array of dictionaries:
NSArray * sortedArray = [myArray sortedArrayUsingComparator:^(id obj1, id obj2) {
NSNumber *rating1 = [(NSDictionary *)obj1 objectForKey:#"date"];
NSNumber *rating2 = [(NSDictionary *)obj2 objectForKey:#"date"];
return [rating1 compare:rating2];
}];
You can sort it easily by using sortArrayUsingComparator:
[array sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
return //pseudo-code: {obj1->dict->date isLaterThan obj2->dict->date};
}];
I sort it. Not sure that my code is clear and well optimized. But here is a solution:
NSMutableArray *masterArray = [NSMutableArray new];
NSMutableArray *sameDates = [NSMutableArray new];
BOOL started = NO;
NSString *prevDate;
for (NSDictionary *dict in sortedArrayWithFiles)
{
NSString *tempString = [dict objectForKey:#"date"];
if (started)
{
if ([tempString isEqualToString:prevDate])
{
[sameDates addObject:dict];
}
else
{
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:tempString forKey:tempString];
[tempDict setValue:sameDates forKey:#"files"];
[masterArray addObject:tempDict];
prevDate = tempString;
[sameDates removeAllObjects];
[sameDates addObject:tempString];
}
}
else
{
// first element
started = YES;
prevDate = tempString;
[sameDates addObject:dict];
}
}
// last value
NSMutableDictionary *tempDict = [[NSMutableDictionary alloc] init];
[tempDict setValue:prevDate forKey:prevDate];
[tempDict setValue:sameDates forKey:#"files"];
[masterArray addObject:tempDict];
In master array we store array with dictionaries separated by date.

Parse a Json Table to a NSMutableArray [duplicate]

This question already has an answer here:
Parsing Json to get all the contents in one NSArray
(1 answer)
Closed 8 years ago.
for the moment I fill in my array directly by a native objective-C code :
Datas *pan1 = [[Datas alloc] initWithTitle:#"My array 1" title:#"Shakespeare's Book" location:#"London"];
Datas *pan2 = [[Datas alloc] initWithTitle:#"My array 2" title:#"Moliere's Book" location:#"London"];
NSMutableArray *datasListe = [NSMutableArray arrayWithObjects:pan1, pan2, nil];
But I want to fill this NSMutableArray by this Json list :
{
"myIndex" : [
{
"name":"My array 1",
"title": "Shakespeare's Book",
"location": "London"
},
{
"name":"My Array 2",
"title": "Moliere's Book",
"location": "Paris"
}
]
}
Anyone have ideas? Thanks much!
This json data can be parse very easily like this.
NSError *e;
NSArray *dic= [NSJSONSerialization JSONObjectWithData: jsondata options: NSJSONReadingMutableContainers error: &e];
NSMutableArray *datasListe = [[NSMutableArray alloc] init];
NSMutableArray *data = [dic objectForKey:#"myIndex"];
//Now you have array of dictionaries
for(NSDictionary *dataDic in data){
NSString *name = [dataDic objectForkey:#"name"];
NSString *title = [dataDic objectForKey#"title"];
NSString *location = [dataDic objectForKey#"location"];
Datas *pan= [[Datas alloc] initWithTitle:name title:title location:location];
[dataList addObject:pan];
}
NSDictionary *firstDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
#"Raja", #"name",
#"Developer", #"title",
#"USA", #"location",
nil];
NSDictionary *secondDictionary = [NSDictionary dictionaryWithObjectsAndKeys:
#"Deepika", #"name",
#"Engieer", #"title",
#"USA", #"location",
nil];
NSMutableArray * arr = [[NSMutableArray alloc] init];
[arr addObject:firstDictionary];
[arr addObject:secondDictionary];
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:arr options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData2 encoding:NSUTF8StringEncoding];
NSLog(#"jsonArray as string:\n%#", jsonString);

Calling NSDictionary with NSArray KeyValue issue

I have an array that loaded with data from other method. The data type is like that in the debug for KEYS as in the code.
<__NSArrayI 0x9e82fc0>(
{
"choice_name" = "Data0";
},
{
"choice_name" = "Data1";
},
{
"choice_name" = "Data2";
},
Then I have called it twice in different method as I commented below and I get the value of the arrray: array0 or array1 nil. Where would be my problem?
- (void)requestPosistion:(ASIFormDataRequest *)request{
NSData *responseData = [request responseData];
NSString *jsonString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSDictionary *result = [jsonString JSONValue];
[jsonString release];
if (![SettingVO isValidResponce:result]) return;
CXMLDocument *doc = [[[CXMLDocument alloc] initWithXMLString:[result objectForKey:#"Response"] options:0 error:nil] autorelease];
NSArray *nodes = [doc nodesForXPath:#"/root" error:nil];
NSLog(#"choiceList is %#", nodes);
if([[[[nodes objectAtIndex:0] attributeForName:#"success"] stringValue] isEqualToString:#"true"])
{
NSArray *nodes3 = NULL;
nodes3 = [doc nodesForXPath:#"/root/cl_choicelist/cl_choice" error:nil];
NSLog(#"node3%#", nodes3);
res = [[NSMutableArray alloc] init];
for (CXMLElement *node in nodes3) {
item = [[NSMutableDictionary alloc] init];
int counter;
for(counter = 0; counter < [node childCount]; counter++) {
[item setObject:[[node childAtIndex:counter] stringValue] forKey:[[node childAtIndex:counter] name]];
}
[item setObject:[[node attributeForName:#"choice_name"] stringValue] forKey:#"choice_name"];
NSLog(#"item %#", item);
[res addObject:item];
[item release];
}
NSLog(#"res %#", res);
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDictionary *plistDict = [[NSDictionary alloc] initWithObjects:res forKeys:res];
//NSArray *keys = [plistDict allKeys];
//NSArray *array0 = [[NSArray alloc] initWithArray:[plistDict valueForKey:#"choice_name"]]; //array0 = nil.
NSArray *array1 = [plistDict objectForKey:#"choice_name"]; //array1 = nil.
Working code looks like that:
[[res objectAtIndex:0] objectForKey:#"choice_name"] //returns Data0
[[res objectAtIndex:1] objectForKey:#"choice_name"] //returns Data1
Most probably you want to use "indexPath" at objectAtIndex:
[[res objectAtIndex:[indexPath row]] objectForKey:#"choice_name"]
<__NSArrayI 0x9e82fc0>( { "choice_name" = "Data0"; }, { "choice_name" = "Data1"; }, { "choice_name" = "Data2"; },
This is an array. Inside the array you have object of NSDictionary with key "choice_name".
So in order to retrieve you need to iterate through the array to get all the kvp.
Replace your line with:
NSString *str = [plistDict valueForKey:#"choice_name"];
You have string for that key nor array.
Is always good to make sure your plistDict is not nil.
In NSDictionary you can have onelly one pair with key #choice_name. Even if you "put" more then one in NSDictionary, all other will just override previous value.
so valueForKey can return onelly one object and not the whole array, because there is onelly one key #choice_name.

Resources