Creating NSDictionary - ios

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

Related

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

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

How to parse such a json array?

Im having hard time while trying to parse the following json array. How to parse it. The other answers in web doesn't seem to solve my problem.
{
"status": 1,
"value": {
"details": [
{
"shipment_ref_no": "32",
"point_of_contact": {
"empid": ""
},
"products": {
"0": " Pizza"
},"status": "2"
},
{
"shipment_ref_no": "VAPL/EXP/46/14-15",
"point_of_contact": {
"empid": "60162000009888"
},
"products": {
"0": "MAIZE/CORN STARCH"
},
"status": "5"
}
]
}
}
I have to access the values of each of those keys.
Following is my code
NSString* pendingResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *jsonData = [pendingResponse dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
NSArray *argsArray = [[NSArray alloc] initWithArray:[jsonDic objectForKey:#"details"]];
NSDictionary *argsDict = [[NSDictionary alloc] initWithDictionary:[argsArray objectAtIndex:0]];
NSLog(#"keys = %#", jsonDic[#"values"]);
This is how you can parse your whole dictionary:
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSArray *details = [[dataDictionary objectForKey:#"value"] objectForKey:#"details"];
for (NSDictionary *dic in details) {
NSString *shipmentRefNo = dic[#"shipment_ref_no"];
NSDictionary *pointOfContact = dic[#"point_of_contact"];
NSString *empId = pointOfContact[#"empid"];
NSDictionary *products = dic[#"products"];
NSString *zero = products[#"0"];
NSString *status = dic[#"status"];
}
NSString *pendingResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *jsonData = [pendingResponse dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
NSArray *argsArray = [[NSArray alloc] initWithArray:[jsonDic objectForKey:#"details"]];
//argsArray holds objects in form of NSDictionary.
for(NSDictionary *response in argsArray) {
//String object
NSLog(#"%#", [response valueForKey:#"shipment_ref_no"]);
//Dictionary object
NSLog(#"%#", [[response objectForKey:#"point_of_contact"] valueForKey:#"empid"]);
//String object
NSLog(#"%#", [response valueForKey:#"status"]);
//Dictionary object
NSLog(#"%#", [[response objectForKey:#"products"] valueForKey:#"0"]);
}
I believe you should surely ask your server developer to update the response format.
Also, you can always use Model classes to parse your data. Please check this, How to convert NSDictionary to custom object.
And yes, I'm using this site to check my json response.
EDIT: Following answer is in javascript!
You can parse your json data with:
var array = JSON.parse(data);
and then you can get everything like this:
var refno = array["value"]["details"][0]["shipment_ref_no"];
you can parse like ...
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
NSDictionary *dictValue = [[NSDictionary alloc] initWithDictionary:[jsonDic objectForKey:#"value"]];
NSArray *arrDetails = [[NSArray alloc] initWithArray:[dictValue objectForKey:#"details"]];
for (int i=0; i<arrDetails.count; i++)
{
NSDictionary *dictDetails=[arrDetails objectAtIndex:i];
NSDictionary *dictContact = [[NSDictionary alloc] initWithDictionary:[dictDetails objectForKey:#"point_of_contact"]];
NSDictionary *dictProduct = [[NSDictionary alloc] initWithDictionary:[dictDetails objectForKey:#"products"]];
}
NSDictionary *response = //Your json
NSArray *details = response[#"value"][#"details"]
etc. Pretty easy
Update your code as follows. You are trying to read the details array from the top level whereas in your data its inside the value key. So you should read the value dict and within that read the details array.
NSString* pendingResponse = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSData *jsonData = [pendingResponse dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonDic = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
NSDictionary *valueDict = [jsonDic objectForKey:#"value"];
NSArray *argsArray = [[NSArray alloc] initWithArray:[valueDict objectForKey:#"details"]];
NSDictionary *argsDict = [[NSDictionary alloc] initWithDictionary:[argsArray objectAtIndex:0]];
NSLog(#"keys = %#", jsonDic[#"values"]);
I think your problem is that you have:
NSLog(#"keys = %#", jsonDic[#"values"]);
But it should be:
NSLog(#"keys = %#", jsonDic[#"value"]);
Below is code for parsing JSON array. i have used to parse JSON array from file but you can also do this using response link also.I have provided code for both and are below.
// using file
NSString *str = [[NSBundle mainBundle] pathForResource:#"test" ofType:#"json"];
NSData *data = [[NSData alloc]initWithContentsOfFile:str];
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSMutableDictionary *dictValues = [[NSMutableDictionary alloc]initWithDictionary:[dict valueForKey:#"value"]];
NSMutableArray *array = [[NSMutableArray alloc]initWithArray:[dictValues valueForKey:#"details"] copyItems:YES];
NSLog(#"Array Details :- %#",array);
// using url
NSURL *url = [NSURL URLWithString:#"www.xyz.com"]; // your url
NSData *data = [[NSData alloc]initWithContentsOfURL:url];
NSMutableDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSMutableDictionary *dictValues = [[NSMutableDictionary alloc]initWithDictionary:[dict valueForKey:#"value"]];
NSMutableArray *array = [[NSMutableArray alloc]initWithArray:[dictValues valueForKey:#"details"] copyItems:YES];
NSLog(#"Array Details :- %#",array);

The operation couldn’t be completed. (Cocoa error 3840.)" (No value for key in object around character 16.)

Below is my sample code
project = #"Project";
projectId=#"ProjectID";
issue =#"Issue";
issueId=#"IssueID";
activity =#"Activity";
activityId=#"ActivityID";
comment =#"Comment";
entryID = #"EntryID";
NSMutableDictionary *entryUser = [[NSMutableDictionary alloc] init];
[entryUser setObject:#"5" forKey:common_Id];
[entryUser setObject:#"Divya Bharathi" forKey:common_Name];
NSMutableDictionary *sdetails = [[NSMutableDictionary alloc] init];
NSMutableArray *time_entry = [[NSMutableArray alloc] init];
// NSMutableArray
//self.dataArray = [[NSMutableArray alloc] init];
NSString *strHours,*wkDay;
for(int i=0;i < [self.dataArray count] ;i++)
{
NSDictionary *dataDic = [self.dataArray objectAtIndex:i];
NSMutableDictionary *projectDic = [[NSMutableDictionary alloc] init];
[projectDic setObject:[dataDic objectForKeyedSubscript:projectId] forKey:common_Id];
[projectDic setObject:[dataDic objectForKeyedSubscript:project] forKey:common_Name];
NSMutableDictionary *issueDic = [[NSMutableDictionary alloc] init];
[issueDic setObject:[dataDic objectForKeyedSubscript:issueId] forKey:common_Id];
NSMutableDictionary *activityDic = [[NSMutableDictionary alloc] init];
[activityDic setObject:[dataDic objectForKeyedSubscript:activityId] forKey:common_Id];
[activityDic setObject:[dataDic objectForKeyedSubscript:activity] forKey:common_Name];
for (int j=0; j<7; j++) {
wkDay=#"";strHours =#"";
wkDay = self.wkDateArray[i];
strHours = [NSString stringWithFormat:#"%#",[dataDic objectForKeyedSubscript:wkDay]];
if(strHours.length)
{
[sdetails setObject:[dataDic objectForKeyedSubscript:entryID] forKey:common_Id];
[sdetails setObject:projectDic forKey:project];
[sdetails setObject:issueDic forKey:issue];
[sdetails setObject:entryUser forKey:currentUser];
[sdetails setObject:activityDic forKey:activity];
[sdetails setObject:strHours forKey:#"hours"];
[sdetails setObject:[dataDic objectForKeyedSubscript:comment] forKey:comment];
[sdetails setObject:wkDay forKey:#"spent_on"];
[time_entry addObject:sdetails];
}
}
}
NSMutableDictionary *results = [[NSMutableDictionary alloc] init];
[results setObject:time_entry forKey:#"entries"];
[results setObject:entryUser forKey:currentUser];
[results setObject:#"2016-01-17" forKey:#"startday"];
[results setObject:#"New" forKey:#"status"];
[results setObject:#"0.0" forKey:#"total"];
NSMutableDictionary *wktime = [[NSMutableDictionary alloc] init];
[wktime setObject:results forKey:#"time"];
NSString *jsonStr = [NSString stringWithFormat:#"%#",wktime];
NSError *jsonError;
NSData *requestData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:requestData options:NSJSONReadingMutableContainers error:&jsonError];
NSLog(#"Json Data : %#",jsonData);
NSLog(#"Error Values: %#",jsonError);
Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be
completed. (Cocoa error 3840.)" (No value for key in object around
character 16.) UserInfo=0x7feb58f21b90 {NSDebugDescription=No value
for key in object around character 16.}
As Avi pointed out,
NSString *jsonStr = [NSString stringWithFormat:#"%#",wktime];
NSData *requestData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:requestData options:NSJSONReadingMutableContainers error:nil];
you have created a string and converted it into NSData, but later trying to use the NSJSON API to convert it into a dictionary, which will fail since the original string isnt json encoded.
You should just convert the dict into Data using the NSJSON API and just read back, although its use wont make much sense till you tell the context.
NSData *requestData = [NSJSONSerialization dataWithJSONObject: wktime options:NSJSONWritingPrettyPrinted error:nil];
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:requestData options:NSJSONReadingMutableContainers error:nil];
If you are trying to do a web request, i would suggest reading AFNetworking docs, that API is well built and can help a lot for web requests.

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

Parsing a JSON array with dictionaries

I'm having some trouble getting to the data I want to in the JSON file. Here is a shortened version of the output from my console:
{
AUD = {
15m = "125.15547";
24h = "124.74";
buy = "121.0177";
last = "125.15547";
sell = "123.44883";
symbol = "$";
};
BRL = {
15m = "120.34";
24h = "120.34";
buy = "120.34";
last = "120.34";
sell = "120.34";
symbol = "R$";
};
CAD = {
15m = "129.08612";
24h = "131.07";
buy = "128.66227";
last = "129.08612";
sell = "129.08612";
symbol = "$";
};
}
I'm trying to parse the file using the built in JSON parsing library. Here is the parser in my viewDidLoad method:
_tickerArray = [NSMutableArray array];
NSURL *tickerDataURL = [NSURL URLWithString:#"https://blockchain.info/ticker"];
NSData *jsonData = [NSData dataWithContentsOfURL:tickerDataURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", dataDictionary);
NSArray *ar = [NSArray arrayWithObject:dataDictionary];
for (NSString *key in [dataDictionary allKeys]) {
for (NSDictionary *dict in ar) {
TickerData *t;
t.currency = [dict objectForKey:key];
t.symbol = [dict objectForKey:#"symbol"];
t.last = [dict objectForKey:#"last"];
[_tickerArray addObject:t];
}
}
I want to store the currency code (like AUD or BRL) into t.currency along with some of the other data contained in the currency dictionary but now my app is crashing.
Error code:
NSInvalidArgumentException', reason: '*** -[__NSArrayM insertObject:atIndex:]: object cannot be nil
None of the objects seem to get added to the _tickerArray
Help?
EDIT: Getting the keys to display with the proper data populating other fields:
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", dataDictionary);
for (NSString *key in [dataDictionary allKeys]) {
NSDictionary *dic=[dataDictionary objectForKey:key];
TickerData *t=[[TickerData alloc] init];
t.currency = key;//EDITED
t.symbol = [dic objectForKey:#"symbol"];
t.last = [dic objectForKey:#"last"];
[_tickerArray addObject:t];
}
t is nil, you have to alloc/ init it:
TickerData *t = [[TickerData alloc] init];
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", dataDictionary);
//NSArray *ar = [NSArray arrayWithObject:dataDictionary];//REMOVED
for (NSString *key in [dataDictionary allKeys]) {
NSDictionary *dic=[dataDictionary objectForKey:key];//ADDED
for (NSString *dickey in [dic allKeys]) { //MODIFIED
NSDictionary *dict=[dic objectForKey:dicKey];//ADDED
TickerData *t=[[TickerData alloc] init];//ALLOC INIT ?
t.currency = key;//EDITED
t.symbol = [dict objectForKey:#"symbol"];
t.last = [dict objectForKey:#"last"];
[_tickerArray addObject:t];
}
}
Your data doesn't contain any array, its all dictionaries, try the above code see comments too..
Hope it works..
Edited:
Yes you have initialize the object too, as suggested above in other answers..
Try it....
NSURL *url = [NSURL URLWithString:#"https://blockchain.info/ticker"];
NSLog(#"API : %#",url);
NSMutableData *jsonData = [NSMutableData dataWithContentsOfURL:url];
NSString *data = [[NSString alloc] initWithBytes: [jsonData mutableBytes] length:[jsonData length] encoding:NSUTF8StringEncoding];
dictionary = [data JSONValue];
NSDictionary *dict = [dictionary objectForKey:#"AUD"];
NSLog(#"%#",dict);
NSString *last = [dict valueForKey:#"last"];
NSLog(#"%#",last);

Resources