getting the value from an NSDictionary of NSDictionaries - json

I am doing a native objC app. ios5
I want to parse a JSON file in the local bundle.
And read each item individually.
To follow is a sample of my JSON file, followed by the code I have working.
I also have explanation of what I think is going on, and the sample code that I need to get assistance with. You are welcome to correct my interpretation as well.
=========================================================================
{"a":[
{"b":{"Q01":"A01","Q02":"B01","Q03":"C01","Q04":"D01","Q05":"E01","Q06":"X","C1":"NR","CABG":"NR","PCI":"NR"}},
{"b":{"Q01":"A01","Q02":"B01","Q03":"C01","Q04":"D01","Q05":"E02","Q06":"X","C1":"I","C1IND":"20","C1SCORE":"3","CABG":"NR","PCI":"NR"}},
{"b":{"Q01":"A01","Q02":"B01","Q03":"C01","Q04":"D01","Q05":"E03","Q06":"X","C1":"NR","CABG":"NR","PCI":"NR"}},
{"b":{"Q01":"A01","Q02":"B01","Q03":"C01","Q04":"D01","Q05":"E04","Q06":"X","C1":"NR","CABG":"NR","PCI":"NR"}},
{"b":{"Q01":"A01","Q02":"B01","Q03":"C01","Q04":"D01","Q05":"E05","Q06":"X","C1":"NR","CABG":"NR","PCI":"NR"}}
]}
My code looks like:
NSString* filePath = [[NSBundle mainBundle] pathForResource:#"nonacs" ofType:#"json"];
NSError* error = nil;
NSData *jsonData = [NSData dataWithContentsOfFile:filePath options:NSDataReadingMappedIfSafe error:&error];
if (jsonData) {
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
if (error) {
NSLog(#"error is %#", [error localizedDescription]);
// Handle Error and return
return;
}
//NSArray *keys = [jsonObjects allKeys];
// not necessary becuase I know the Root key is a single "a"
NSString* jsonString = [NSString stringWithFormat:#"%#",[jsonObjects objectForKey:#"a"]];
tLabel01.text = [NSString stringWithFormat:#"jsonData Length is = %d", [jsonData length]];
NSDictionary* dict01 = [[NSDictionary alloc] initWithDictionary:jsonObjects];
l2.text = [NSString stringWithFormat:#"dict01 length = %d", dict01.count];
NSDictionary* dict02 =[[NSDictionary alloc] initWithDictionary:dict01];
l3.text = [NSString stringWithFormat:#"dict2.length = %d", dict02.count];
//NSArray* array01 = [[NSArray alloc] initWithObjects:dict01, nil];
//NSArray *allvalues = [jsonObjects allValues];
//NSArray *allvalues = [[jsonObjects initWithContentsOf ] allValues];
//l3.text = [NSString stringWithFormat:#"allvalues.count = %d", allvalues.count];
//NSDictionary *dictB = [dict01 objectForKey:#"b"];
//l3.text = [NSString stringWithFormat:#"dictB.count = %d", dictB.count];
l3.text = [NSString stringWithFormat:#"jsonObject count = %d", [[jsonObjects objectForKey:#"a"] count]];
// this works really well... except it returned 1700, and there should only be 1550
//l4.text = #"nada";
//[[jsonObjects objectForKey:#"a"] count]]
NSArray *array = [jsonObjects objectForKey:#"a"];
NSArray *arrayVariable = [array objectAtIndex:0];
//l4.text = [NSString stringWithFormat:#"Q01 = %#", [arrayVariable objectForKey: #"Q01"]];
//l4.text =[NSString stringWithFormat:#"arrayVariable count = %d", arrayVariable.count];
NSArray *arrayb = [jsonObjects objectForKey:#"b"];
l4.text = [NSString stringWithFormat:#"arrayb count = %d", arrayb.count];
bTV01.text = jsonString;
};
=============================================================================
The root Object is an NSDictionary with single Key "a".
The value corresponding to that value is an NSArray.
The array contains NSDictionaries with a single Key "b".
The B NSDictionaries contain another NSDictionary.
could someone show me the code to display the 3rd B NSDictionary value for "Q02" please
thanks

[[[root objectForKey:#"a"] valueForKey:#"b"] objectAtIndex:2]

Related

Objective C String to JSON formatting

Quick disclaimer. I've programmed Java for years but this is the first Objective C I've ever written.
I've written some code which almost unfortunately works but frankly hurts my eyes with the number of lines of code and quality. Basically looking for the right way to convert the original string:
<TUHandle 0x280479f50 type=PhoneNumber, value=07700000000, normalizedValue=(null), isoCountryCode=(null)>
Into JSON (ignoring the TUHandle 0x280479f50) part which I don't need:
{"value": "07700000000",
"normalizedValue": "(null)",
"type": "PhoneNumber",
"isoCountryCode": "(null)"}
Line breaks and indents are NOT important, only that this is valid JSON
//Format of string
//<TUHandle 0x280479f50 type=PhoneNumber, value=07700000000, normalizedValue=(null), isoCountryCode=(null)>
NSString *original = [NSString stringWithFormat:#"%#", hand];
//Trim off unused stuff
NSRange startKeyValues = [original rangeOfString:#"type="];
NSRange endKeyValues = [original rangeOfString:#">"];
NSRange rangeOfString = NSMakeRange(startKeyValues.location, endKeyValues.location - startKeyValues.location);
NSString *keysValues = [original substringWithRange:rangeOfString];
//Create a dictionary to hold the key values
NSMutableDictionary *dict = [[NSMutableDictionary alloc]initWithCapacity:10];
//Split the keysValuesstring
NSArray *items = [keysValues componentsSeparatedByString:#","];
for (NSString* o in items)
{
//Create key value pairs
NSArray *item = [o componentsSeparatedByString:#"="];
NSString *key=[item objectAtIndex:0];
NSString *value=[item objectAtIndex:1];
[dict setObject:value forKey:key];
}
[dict setObject:currentUUID forKey:#"uid"];
//Convert to Json Object
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:dict options:0 error:nil];
Any tips which would make this look a hell of a lot less clunky?
Depending on what parts of the format you're comfortable with hardcoding, this may serve.
It assumes that only parts of the input string that look like "x=y" go into the json, and cuts off the last character from y's value, since that's either a "," or the trailing ">".
- (void) tuhandleToJSON {
NSString* input = #"<TUHandle 0x280479f50 type=PhoneNumber, value=07700000000, normalizedValue=(null), isoCountryCode=(null)>";
NSMutableDictionary<NSString*, NSString*>* dict = [NSMutableDictionary dictionary];
NSArray* tokens = [input componentsSeparatedByString:#" "];
for (NSString* token in tokens) {
NSArray<NSString*>* parts = [token componentsSeparatedByString:#"="];
if (parts.count != 2) {
continue;
}
NSString* key = parts[0];
NSString* value = parts[1];
NSUInteger index = value.length - 1;
dict[key] = [value substringToIndex:index];
}
NSError* error;
NSData* data = [NSJSONSerialization dataWithJSONObject:dict options:NSJSONWritingPrettyPrinted error:&error];
NSString* json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"%#", json);
}

How to parse JSON response received from a Webservice Response

I Have got this Response from WebService
{"d":"{"token":"b502645e-837f-4237-a6ff-d4323f2799dd","timestamp":"09/11/20147:46:43PM"}"}
I want to Parse this String so that i can get output like :
token = b502645e-837f-4237-a6ff-d4323f2799dd
timestamp = 09/11/20147:46:43PM
So that i can Store it into Database.
This is my Code
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
// The request is complete and data has been received
// You can parse the stuff in your instance variable now
/*
NSError *errorJson=nil;
NSString* OuterDict = [NSJSONSerialization JSONObjectWithData:receivedData options:kNilOptions error:&errorJson];
NSLog(#"Outer Dictionary %#",OuterDict);
*/
NSString *responseData = [[NSString alloc]initWithData:receivedData encoding:NSUTF8StringEncoding];
responseData = [responseData stringByReplacingOccurrencesOfString:#" " withString:#""];
responseData = [responseData stringByReplacingOccurrencesOfString:#"\\" withString:#""];
//NSString* encodedString = [responseData stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
//NSLog(#"%#",encodedString);
NSLog(#"Reponse data %#",responseData);
NSError *errorJson=nil;
NSData *jsonData = [responseData dataUsingEncoding:NSUTF8StringEncoding];
jsonData = [jsonData subdataWithRange:NSMakeRange(0, [jsonData length] - 1)];
NSDictionary* OuterDict = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&errorJson];
NSLog(#"Outer Dict %#",OuterDict);
}
I am getting null as Output:
Outer Dict (null)
Can Anyone Help me With this.
Thanks In Advance.
Use following snippets at the top of your method. it will parse your JSON data and returns dictionary. You can perform any operations on Dictionary according to your need.
NSDictionary *dictResponse = [NSJSONSerialization JSONObjectWithData:receivedData options:NSJSONReadingAllowFragments error:&err];
NSLog(#"Response : %#", dictResponse);
Happy coding :)

fteching jSON causing application to crash ?? What should I have to do resolve it.I want to store response in userObj.movie_rating

json is:
{
"Title":"Kick", "Year":"2009", "Rated":"N/A", "Released":"08 May 2009",
"Runtime":"N/A", "Genre":"Comedy, Romance, Thriller", "Director":"Reddy Surender",
"Writer":"Abburi Ravi (dialogue), Reddy Surender (screenplay), Vakkantham Vamsi (story)",
"Actors":"Ravi Teja, Ileana, Shaam, Ali",
"Plot":"A guy with an abnormal lifestyle tries to find thrill and pleasure in every work he does and finally becomes a thief.",
"Language":"Telugu", "Country":"India", "Awards":"1 nomination.",
"Poster":"N/A","Metascore":"N/A",
"imdbRating":"7.6",
"imdbVotes":"736",
"imdvid":"tt1579592",
"Type":"movie",
"Response":"True"
}
The Code is:
-(void)parseData:(NSData *)data
{
NSString *responseString = [[NSString alloc] initWithData:data
encoding:NSUTF8StringEncoding];
NSLog(#"responseString %#",responseString);
NSError *error;
NSArray *json = [NSJSONSerialization JSONObjectWithData:data
options:(kNilOptions)
error:&error];
NSLog(#"json data == %#", json);
NSMutableArray *response =[[NSMutableArray alloc]init];
for (int i = 0; i < json.count; i++)
{
response = [json valueForKey:#"imdbRating"];
User * userObj = [[User alloc]init];
userObj.movieRating = [json valueForKey:#"imdbRating"];
[response addObject:userObj];
}
[delegate getIMDBMovie_Rating:response];
}
How to save data in bussiness model object for key imdbRating
The Json you specified is not an array. This is an NSDictionary object. Also as this is a NSDictionary you don't need to use for loop.
Second thing you are doing wrong with your response variable.
you did:
response = [json valueForKey:#"imdbRating"];
User * userObj = [[User alloc]init];
userObj.movieRating = [json valueForKey:#"imdbRating"];
[response addObject:userObj];
here response variable is not an array even though you allocated it as NSMutableArray earlier. As you assign new value in response in the line: response = [json valueForKey:#"imdbRating"];
your variable type will be either NSNumber or NSString based on the type of [json valueForKey:#"imdbRating"].
So remove the line response = [json valueForKey:#"imdbRating"]; and it will work.
By doing this you will hv an array of User objects containing imdbRatings.
UPDATE
According to your comment your code has:
-(void)getIMDBMovie_Rating:(NSMutableArray*)retrievedData {
if (retrievedData.count > 0)
{
userObj = [retrievedData objectAtIndex:0];
NSLog(#"%#is the value",retrievedData);
iMDB_MovieRatingLabel.text=userObj.movieRating;
}
}
Problem is in your getIMDBMovie_Rating. as your method is accepting NSMutableArray as parameter. But when you supply value for your method is NSDictionay [delegate getIMDBMovie_Rating:response]; (you can check by NSLog(#"%#", [response class]);).
So in your getIMDBMovie_Rating method you are accessing [retrievedData objectAtIndex:0];. objectAtIndex is not available with NSDictionay that's why your app get crash.
Try like this,
-(void)parseData:(NSData *)data
{
NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"responseString %#",responseString);
NSError *error;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:(kNilOptions) error:&error];
NSLog(#"json data == %#", json);
NSMutableArray *response =[[NSMutableArray alloc]init];
NSArray *aArray = [json valueForKey:#"imbdRating"];
for (NSDictionary *dictionary in aArray)
{
/* Create a initWithData method in your User Model class and pass the dictionary object to it like,
- (id) initWithData:(NSDictionary *) jsonDictionary
{
self=[super init];
if(self)
{
self.movieRating =[json valueForKey:#"imdbRating"];
} */
User * userObj = [[User alloc]initWithData:dictionary];
[response addObject:userObj];
}
[delegate getIMDBMovie_Rating:response];
}

Show JSON content depending on user id iOS

I want to show the content depending on user id.
The user log-in to the App, after the successful login, he will see the content depending on his id that is retrieved from the JSON file which is connected the the external mysql database.
- (void)viewDidLoad
{
[super viewDidLoad];
NSURL *jsonURL = [NSURL URLWithString:#"http://api.example.com/page.php?user_id=1"];
NSData *jsonData = [NSData dataWithContentsOfURL:jsonURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#",dataDictionary);
self.something = [dataDictionary objectForKey:#"something"];
}
My problem is :
How to make " 1 " in ( user_id=1 ) dynamic, in a way, it will be changed automatically when the user log-in to his account.
Prepare URL dynamically
NSString *userID = #"23";//Get your userID after login
NSURL *jsonURL = [NSURL URLWithString:[NSString stringWithFormat:#"http://api.example.com/page.php?user_id=%#",userID];
you can use StringWithFormat Method of NSString Class, This methods helps you in creating dynamic NSString Objects,
- (void)viewDidLoad
{
[super viewDidLoad];
NSString userId = #"your user id here";
NSURL *jsonURL = [NSURL URLWithString:[NSString StringWithFormat:#"http://api.example.com/page.php?user_id=%#",userId]];
NSData *jsonData = [NSData dataWithContentsOfURL:jsonURL];
NSError *error = nil;
NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#",dataDictionary);
self.something = [dataDictionary objectForKey:#"something"];
}

Trouble on parsing JSON and displaying it on UITableView

I have this url: http://maps.google.com.br/maps/api/directions/json?origin=porto+alegre&destination=novo+hamburgo&sensor=false
And this code:
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
[connection release];
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
[responseData release];
NSMutableDictionary *theDictionary = [responseString JSONValue];
NSLog(#"%#", theDictionary);
[responseString release];
if (theDictionary != nil)
{
NSArray *routesArray = [theDictionary objectForKey:#"routes"];
NSDictionary *firstRoute = [routesArray objectAtIndex:0];
NSArray *legsArray = [firstRoute objectForKey:#"legs"];
NSDictionary *firstLeg = [legsArray objectAtIndex:0];
steps = [firstLeg objectForKey:#"steps"];
}
[tableView reloadData];
}
I want to display every single #"html_instructions" on a uitableview.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [self.steps count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:#"cachedCell"];
if (cell == nil)
cell = [[[UITableViewCell alloc]
initWithFrame:CGRectZero reuseIdentifier:#"cachedCell"] autorelease];
return cell;
}
What's missing in my code??? Should be some little detail... any help would be GREAT!
I would do it like this:
Create url request with your url
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]init];
[request setURL:[NSURL URLWithString:#"http://maps.google.com.br/maps/api/directions/json?origin=porto+alegre&destination=novo+hamburgo&sensor=false"]];
then create NSData structure, that holds response to the request and I converted it to string
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; //Or async request
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
After that, you load JSON into Dictionary, then to move one level down, pass it to another dictionary (result 1)
NSError *error=nil;
result = [NSJSONSerialization JSONObjectWithData:returnData options:kNilOptions error:&error];
result1 = [result objectForKey:#"routes"];
result2 = [result1 objectForKey:#"legs"];
Then move it into NSMutableArray
jsonMutArray= [result2 objectForKey:#"steps"];
From there, you just put label into your custom cell attach it as a IBOutlet, synthetize and do in cellForRowAtIndexPath method
cell.yourLabel.text = [jsonMutArray objectForKey:#"html_instructions"];
However, keep in mind, that I'm just begginer, so this might not be the most effective way of doing it :) Good Luck!
Don't you need to be doing something like this in your CellForRowAtIndexPath ?
NSString *cellValue = **WHATEVER VALUE YOU WANT TO PUT IN**;
cell.textLabel.text = cellValue;
return cell;
I don't see you adding your data to the cell.