How to parse JSON data from textual file in Objective-C - ios

I know, JSON parsing questions are asked over and over again, but still I can't find any answer to this one.
I've been trying to read and parse a textual JSON file using NSJSONSerialization to no avail.
I've tried using the same JSON data from a NSString and it did work.
Here's the code:
NSError *error;
NSString *jsonString1 = [NSString stringWithContentsOfFile:jsonFilePath
encoding:NSUTF8StringEncoding
error:&error];
NSData *jsonData1 = [jsonString1 dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonObject1 = [NSJSONSerialization JSONObjectWithData:jsonData1
options:0
error:&error];
NSString *jsonString2 = #"{\"key\":\"value\"}";
NSData *jsonData2 = [jsonString2 dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *jsonObject2 = [NSJSONSerialization JSONObjectWithData:jsonData2
options:0
error:&error];
- The text file contains one line: {"key":"value"}
- jsonString1 = #"{"key":"value"}"
- jsonString2 = #"{\"key\":\"value\"}"
- jsonData1 is 23 bytes in size
- jsonData2 is 15 bytes in size
- jsonObject1 is nil and I get error code 3840
- jsonObject2 is a valid dictionary
Seems like the problem is with reading the file, since the NSStrings and NSDatas differ, but what am I doing wrong here and how can I fix it?

Most likely you file contains some unprintable characters (e.g. \0) that trigger the failure. Printing the error message will tell you at what position the first invalid characters occurs.
For example, try printing "{\"key\":\u{0000}\"value\"}" and you'll seem to get a valid JSON, however decoding it fails.

I always do a check on the return value when doing anything with NSUTF8StringEncoding and if nil, then try NSASCIIStringEncoding:
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
if (jsonString == nil) {
jsonString = [[NSString alloc] initWithData:jsonData encoding:NSASCIIStringEncoding];
}
return jsonString;

Related

Creating a json object dynamically

I have to make json request of following type.
{
"documents": [
{
"file_size": 48597,
"file_name": "pisa-en.pdf",
"file_content": "base64String"
}
]
}
Following is the way how im creating the json.
NSString *json = [NSString stringWithFormat:#"{\"documents\": [ { \"file_size\": %#, \"file_name\": %#\", \"file_content\": \"%#\" } ]}",_imageSizeArray[0],_imageNameArray[0],_baseArray[0]];
but the problem is that, the documents array may even contain more than one json object within it. If thats the case How can i create a jsonobject dynamically and embed it within documents array?
You have to take Array and add document object in that array
than at request time you have to convert your array to json string by following code
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:myArray options:NSJSONWritingPrettyPrinted error:&error];
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];

Getting null from NSDictionary when NSJSONSerialization is being used

I am new to developing and stackoverflow please help me. i am trying to do a simple application where the YQL link is used to get local data and display it in table format. For that i am converting the data into dictionary , later i want to send it into table. But when i tried to convert data to Dictionary it says null. Please help me. Check the Screenshot below. Thanks in advance.
NSString *str = #"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20local.search%20where%20zip%3D'94085'%20and%20query%3D'pizza'&diagnostics=true";
Here i took json query into a string (*str)
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
// NSString *stringFromData = [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding];
// NSLog(#"%#", stringFromData);
When i tried to implement this commented code im getting the result as expected, but i want to put all the data into dictionary and display it, so i tried to convert the data into dictionary
NSDictionary *dataFromWeb = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil];
NSDictionary *queryDict = [dataFromWeb objectForKey:#"query"];
NSDictionary *results = [dataFromWeb objectForKey:#"results"];
NSString *allResults = [queryDict objectForKey:#"Results"];
NSLog(#"%#", dataFromWeb);
}
The response returning from Yahoo API is XML by default. You should append format=json to the querystring in order to get the response in JSON format so you can parse it using NSJSONSerialization class:
https://query.yahooapis.com/v1/public/yql?format=json&q=select...
Your Api Return xml data so you need to do xml parsing
NSJSONSerialization is used for json parsing
NSString *str = #"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20local.search%20where%20zip%3D'94085'%20and%20query%3D'pizza'&diagnostics=true";
NSURL *UrlFromStr = [NSURL URLWithString:str];
hit this UrlFromStr on your browser you see it return xml data not json
use NSXMLParser to parse xml data
Please Use NSXMLParser To Parse xml data instead of NSJSONSerialization.
NSJSONSerialization is used to parse JSON data.
Declare in .h file
#property (nonatomic, strong) NSXMLParser *xmlParser;
in .m file.
NSString *str = #"https://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20local.search%20where%20zip%3D'94085'%20and%20query%3D'pizza'&diagnostics=true";
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:str]];
self.xmlParser = [[NSXMLParser alloc] initWithData:data];
self.xmlParser.delegate = self;
// Initialize the mutable string that we'll use during parsing.
self.foundValue = [[NSMutableString alloc] init];
// Start parsing.
[self.xmlParser parse];
The format of objects you wanna parse is XML,but you use the class of ParseJSON to parse it ,so it return NULL.You can use the class of NSXML to parse it and then set its delegate to execute the related methods...Good luck to you ..
your Api is not a json its XML format use the XML Parser, visit below link,
http://www.theappguruz.com/blog/xmlparsing-with-nsxmlparser-tutorial
hope its helpful.

Parse JSON data is returning null value

I am getting JSON data with below code as string. But really very confusing to solve this
NSString *htmlSTR = [[NSString alloc] initWithData:self.receivedData
encoding:NSUTF8StringEncoding];
NSLog(#"userdetail :%#" , htmlSTR);
But i need to parse the Id only.
I parsed with the code of
NSDictionary *JsonDict = [NSJSONSerialization JSONObjectWithData:self.receivedData options: NSJSONReadingMutableContainers error: &e];
NSLog(#"json %#",jsonArr1);
NSString *string=[JsonDict valueForKey:#"Id"];
But its returning null value for string, even for integer it is returning numeric zero
userdetail : {"Country":"Afghanistan","CreatedBy":"raje#gmail.com","FirstName":"rajeev","Gender":"M","LastName":"leader","ModifiedBy":"raje#gmail.com","Password":"asdf","emails":"raje#gmail.com","id":32}
This is the first time am trying this thing, help me to solve this.Sorry for bad formatting.
only change this line .
NSString *string=[JsonDict valueForKey:#"Id"];
TO
NSString *string=[JsonDict valueForKey:#"id"];
Hope this works for you.

JSONObjectWithData and umlauts

I am using a service (not mine) that supplies JSON-formatted data. When I try to parse the data with JSONObjectWithData:options:error:, it returns nil if there is an umlaut (ö, for example). It works fine if there are no umlauts or other special characters.
The person running the service says the data is encoded as ISO-8859-1 (not UTF-8).
Is there anything I can do at my end to get such data to parse correctly?
Try with below piece of code:
NSError *error;
NSString *string = [NSString stringWithContentsOfURL:webURL encoding:NSISOLatin1StringEncoding error:&error];
NSData *utf8Data = [string dataUsingEncoding:NSUTF8StringEncoding];
id jsonObject = [NSJSONSerialization JSONObjectWithData:utf8Data options:kNilOptions error:&error];
if (error) {
//Error handling
} else {
//use your json object
}
if you have NSData with latin1 (ISO-8859-1) then you may want to convert it to UTF-8 first, like this:
const char latin1[1] = {196}; // iso-8859-1 umlaut character code
NSData *latin1Data = [NSData dataWithBytes:latin1 length:1];
NSString* utfstr = [[NSString alloc] initWithCString:latin1Data.bytes encoding:NSISOLatin1StringEncoding];
NSLog(#"%#",utfstr);

NSData to NSString with JSON response

NSData* jsonData is the http response contains JSON data.
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"jsonString: %#", jsonString);
I got the result:
{ "result": "\u8aaa" }
What is the proper way to encoding the data to the correct string, not unicode string like "\uxxxx"?
If you convert the JSON data
{ "result" : "\u8aaa" }
to a NSDictionary (e.g. using NSJSONSerialization) and print the dictionary
NSError *error;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error];
NSLog(#"%#", jsonDict);
then you will get the output
{
result = "\U8aaa";
}
The reason is that the description method of NSDictionary uses "\Unnnn" escape sequences
for all non-ASCII characters. But that is only for display in the console, the dictionary is correct!
If you print the value of the key
NSLog(#"%#", [jsonDict objectForKey:#"result"]);
then you will get the expected output
說
I don't quite understand what the problem is. AFNetworking has given you a valid JSON packet. If you want the above code to output the character instead of the \u… escape sequence, you should coax the server feeding you the result to change its output. But this shouldn't be necessary. What you most likely want to do next is run it through a JSON deserializer…
NSDictionary * data = [NSJSONSerialization JSONObjectWithData:jsonData …];
…and you should get the following dictionary back: #{#"result":#"說"}. Note that the result key holds a string with a single character, which I'm guessing is what you want.
BTW: In future, I suggest you copy-paste output into your question rather than transcribing it by hand. It'll avoid several needless rounds of corrections and confusion.

Resources