Reading value from JSON - help writing the logic - iphone

I have the JSON in the format of
{"index":"0","name":"jemmy","age":"2"}
I need to extract the values stored and save it; I have done the following, but it doesn't work
Terminating app due to uncaught exception
'NSInvalidArgumentException', reason: '-[NSCFString objectForKey:]:
unrecognized selector sent to instance 0x6671a10'
my code
NSDictionary *dictionary = [request responseHeaders];
SBJsonParser *parser = [SBJsonParser new];
id content = [responseString JSONValue];
NSDictionary *dealDictionary = content;
NSArray *array = [dealDictionary allKeys];
for (NSString *str in array)
{
NSDictionary *childDictionary = [dealDictionary objectForKey:str];
NSLog(#"%# ",[childDictionary objectForKey:#"name"]);
}

You may not understand how to use SBJSON, maybe a quick read through the documentation would be useful. First, you need to actually use the parser that you create:
SBJsonParser *parser = [SBJsonParser new];
NSDictionary *content = [parser objectWithString:[request responseString]];
Secondly, you can traverse your dictionary slightly easier as such:
NSEnumerator *enum = [content keyEnumerator];
id key;
while (key = [enum nextObject]) {
NSLog(#"key %# and object %#",key,[content objectForKey:key]);
}

Related

NSdictionary is not Null, but showing 0 key/value

I am fetching data from server using json. It is checked url is getting hit response is received, printed in console all values fetched from json. But dictionary and tried with array also both are showing null values by breakpoints but when printed in console showing data is fetched. Below is the code.
NSString *urlStr = [NSString stringWithFormat:#"http://server39.pivbfg.com/360ads/apps/ads/%#/android/1360/ord0.9109502528132325?json=1&package_url=%#",self.mStrPid, base64String];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:
[NSURL URLWithString:
[urlStr stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding]]];
NSLog(#"req-------------%#",request);
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSDictionary *json_dict = [json_string JSONValue];
NSLog(#"json_dict\n%#",json_dict);
NSLog(#"json_string\n%#",json_string);
NSMutableArray *arrAds = [[NSMutableArray alloc]init];
arrAds = [json_dict valueForKey:#"ads"];
request is going ok.
json_string is ok.
But json_dict printing values in console but showing null at breakpoints. What could be the reason for this. One thing is i am using ARC, does it affect this code. Please guide for the above.
This is the error: * Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSCFString 0x9851e00> valueForUndefinedKey:]: this class is not key value coding-compliant for the key ads.'* First throw call stack:
(0xb5012 0x13a9e7e 0x13dfb1 0xe565ed 0xdc28db 0xdc288d 0x613d 0x3d1707 0x3d1772 0x320915 0x320caf 0x320e45 0x329e57 0x5942 0x2ed697 0x2edc87 0x2eee8b 0x3001f5 0x30112b 0x2f2bd8 0x2202df9 0x2202ad0 0x2abf5 0x2a962 0x5bbb6 0x5af44 0x5ae1b 0x2ee6ba 0x2f053c 0x544d 0x2b65 0x1)
libc++abi.dylib: terminate called throwing an exception
Edited code
NSData *response = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *json_string = [[NSString alloc] initWithData:response encoding:NSUTF8StringEncoding];
NSError *error;
NSData *jsonData = [json_string dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *results = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"results\n%#",results);
NSMutableArray *arrAds = [[NSMutableArray alloc]init];
arrAds = [results valueForKey:#"ads"];
NSLog(#"dict-------------%#",arrAds);
Now the same problem is coming with the array arrAds. It is printing values in console but empty.
Well the error tells you that the property you are retrieving from the JSON is not a dictionary but a string. It looks like you json_string does not contain a valid JSON object.
In your example you'r also leaking:
NSMutableArray *arrAds = [[NSMutableArray alloc]init];
arrAds = [json_dict valueForKey:#"ads"];
You create a new NSMutableArray only to assing a new object to the same variable the next line. Also the object returned will not a none mutable version. You can just replace it with:
NSMutableArray *arrAds = [[json_dict objectForKey:#"ads"] mutableCopy];

Read/Write plist on iPhone iOS 5

I am studying iPhone development and facing a problem with a reading/writing plist file. I followed an example from a iPhone development book but keep getting an error message when running.
The error message says : 2012-04-26 00:21:09.759 FileHandling[5915:207] -[__NSCFDictionary addObject:]: unrecognized selector sent to instance 0x685ac40
Here is the example code (it seems fine to me...though):
NSString *plistFileName = [[self documentPath] stringByAppendingPathComponent: #"Apps.plist"];
NSLog(#"Where is the file? => %#", plistFileName);
if ([[NSFileManager defaultManager] fileExistsAtPath:plistFileName]) {
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:plistFileName];
for (NSString *category in dict) {
NSLog(#"%#", category);
NSLog(#"=========");
NSArray *titles = [dict valueForKey:category];
for (NSString *title in titles) {
NSLog(#"%#", title);
}
}
} else {
NSString *plistPath = [[NSBundle mainBundle] pathForResource:#"Apps" ofType: #"plist"];
NSLog(#"%#", plistPath);
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile: plistPath];
NSLog(#"Let's take a look : %#", dict);
NSMutableDictionary *copyOfDict = [dict mutableCopy];
NSLog(#"Let's look at the mutable dictationary : %#", copyOfDict);
NSArray *categoriesArray = [[copyOfDict allKeys] sortedArrayUsingSelector: #selector(compare:)];
for (NSString *cateogry in categoriesArray) {
NSArray *titles = [dict valueForKey: cateogry];
NSMutableArray *mutableTitles = [titles mutableCopy];
[mutableTitles addObject: #"New App Title"];
[copyOfDict setObject: mutableTitles forKey:cateogry];
}
NSString *fileName = [[self documentPath] stringByAppendingPathComponent: #"Apps.plist"];
[copyOfDict writeToFile: fileName atomically:YES];
}
According to the error message, the problem is occurring in the call to addObject: on an __NSCFDictionary. This means that, at runtime, a dictionary received a message to add an object.
However, in this code snippet, addObject: is apparently being sent to an NSMutableArray. This probably means that each object titles you're retrieving from dict in the last for-loop is not an array, but in fact another dictionary, that your code is simply referring to as an array.
Indeed, your code does seem well-formed, so check the well-formedness of your source plist; open it up in a plain text editor. Also, you use a ton of logging, so confirm this way: in the output, dictionaries (including the root entry) are denoted by {curly = braces}, where arrays are denoted by (round parentheses).

NSPropertyListSerialization after parsing an XML

I need to know if I am in the right track here. I am parsing an XML-RPC in iPhone (using the eczarny framework) and I am getting an array with objects. I create an NSData and store an object. After that I am trying to deserialize it but get en error.
Code:
NSArray *result = [response object];
NSData *data = [result objectAtIndex:0];
NSLog(#"Data %#",data);
NSDictionary * message = nil;
NSString * error = nil;
message = [NSPropertyListSerialization propertyListFromData:data mutabilityOption:NSPropertyListMutableContainers format:nil errorDescription:&error];
The nslog:
Data {
DESCRIPTION = "Standardverkn";
FLAGS = 0;
NAME = "Fenster OG3";
RECEIVER = "IEQ007:3";
SENDER = "IEQ0043:1";
}
The error:
-[__NSCFDictionary length]: unrecognized selector sent to instance 0x6e4bd50
What am I doing wrong?
[result objectAtIndex:0] is already an NSDictionary. You don't need to deserialize it. You can just directly use it as the message.
(If it is an NSData, the NSLog will show something like <12345678 9abcdef0 ...>.)

EXC_BAD_ACCESS whilst parsing JSON using SBJSON. Corresponding message states variable json_string is not a CFString

I have the following response from server side:
{"_playLists":[{"name":"Playlist 1","items":[{"name":"Poza 1","target":"http:\/\/myaudi.fr","url":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/image\/pic1_iphone3.jpg","url_thumb":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/thumb\/pic1_iphone3_thumb.jpg"},{"name":"Poza 2","target":"http:\/\/audifrance.fr","url":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/image\/pic2_iphone3.jpg","url_thumb":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/thumb\/pic2_iphone3_thumb.jpg"}]},{"name":"Playlist 2","items":[{"name":"Poza 3","target":"http:\/\/google.ro","url":null,"url_thumb":null}]}]}
And I'm trying to acces this by using:
SBJSON *parser = [[SBJSON alloc] init];
NSString *responseString = [request responseString];
NSString *json_string = [[NSString alloc] initWithData:responseString encoding:NSUTF8StringEncoding];
NSArray *statuses = [parser objectWithString:json_string error:nil];
But I get EXC_BAD_ACCESS at this line
NSString *json_string = [[NSString alloc] initWithData:responseString encoding:NSUTF8StringEncoding];
saying variable json_string is not a CFString.
Can someone help me solve this and tell me how to act further to acces the JSON components?Thank you:)
EDIT:
{
items = (
{
name = "Poza 1";
target = "http://myaudi.fr";
url = "http://test.res-novae.fr/sfrplay/upload/image/pic1_iphone3.jpg";
"url_thumb" = "http://test.res-novae.fr/sfrplay/upload/thumb/pic1_iphone3_thumb.jpg";
},
{
name = "Poza 2";
target = "http://audifrance.fr";
url = "http://test.res-novae.fr/sfrplay/upload/image/pic2_iphone3.jpg";
"url_thumb" = "http://test.res-novae.fr/sfrplay/upload/thumb/pic2_iphone3_thumb.jpg";
}
);
name = "Playlist 1";
},
{
items = (
{
name = "Poza 3";
target = "http://google.ro";
url = "<null>";
"url_thumb" = "<null>";
}
);
name = "Playlist 2";
}
You should use one of the JSON frameworks available out there, i.e. JSONKit or json-framework, which both makes it really easy to convert strings to JSON objects (i.e. an NSDictionary).
If you're using json-framework, you'd only have to do the following (if you've included JSON.h):
NSDictionary *jsonObject = [responseString JSONValue];
There is a issue with your line
NSString *json_string = [[NSString alloc] initWithData:responseString encoding:NSUTF8StringEncoding];
you have declared responseString as NSString *responseString = [request responseString];
and you are giving it as Data while allocating json_string
You do not need this line
NSString *json_string = [[NSString alloc] initWithData:responseString encoding:NSUTF8StringEncoding];
responseString is already a string (and initWithData: expects a NSData object not NSString). Just feed it straight to the parser:
NSArray *statuses = [parser objectWithString:responseString error:nil];
Can someone help me solve this and tell me how to act further to acces
the JSON components?
You now have a nice NSArray of NSDictionary objects representing your JSON data, you can access the first item, represented by
{"name":"Playlist 1","items":[{"name":"Poza 1","target":"http:\/\/myaudi.fr","url":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/image\/pic1_iphone3.jpg","url_thumb":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/thumb\/pic1_iphone3_thumb.jpg"},{"name":"Poza 2","target":"http:\/\/audifrance.fr","url":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/image\/pic2_iphone3.jpg","url_thumb":"http:\/\/test.res-novae.fr\/sfrplay\/upload\/thumb\/pic2_iphone3_thumb.jpg"}]}
by getting the first element in the array
NSDictionary* dict = [statuses objectAtIndex:0];
and the keys in the dictionary should be "name", and "items". The object for "name" will be an NSString and the object for "items" will be an NSArray containing further NSDictionary objects describing each item.

Cast JSON object (NSCFDictionary) to string and parse it

I'm working with facebook connect and trying to handle the JSON object that i'm receiving.
I invoked the requstWithGraphPath method and need to get back a JSON object,
tried to parse it and getting an error:
SBJSON *parser = [[SBJSON new] autorelease];
NSData *data = [[NSData alloc] initWithData:result];
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; -> in this line - "[__NSCFDictionary length]: unrecognized selector sent to instance"
NSArray *events = [parser objectWithString:jsonString];
What's the problem?
Can I get the string in an other way or parse the object differently?
Thanks.
If you are working with the delegate callback
- (void)request:(FBRequest *)request didLoad:(id)result;
the parsing work has been done for you. Traverse the NSDictionary or NSArray to find the data you are looking for. If you are working with the delegate callback
- (void)request:(FBRequest *)request didLoadRawResponse:(NSData *)data;
you should initialize an NSString with the data, and use the category method that SBJSON adds to NSString for creating an id. That is assuming the data is data that constructs a string.
NSString *jsonString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
id result = [jsonString JSONValue];
Are you sure the error happens on that line, or does it happen on the line above?
If result is an NSDictionary (or CFDictionary, same thing), then it is already parsed and you do not need to do that yourself — and it could cause that error message too, on the line above.
The line:
data = [[NSData alloc] initWithData:result];
is almost certainly not what you want to do, as it is equivalent to
data = [result copy];
assuming that result is an NSData object (or NSMutableData), which I'm guessing it isn't.