JSON parsing iOS - ios

I am having a problem in parsing JSON url in my iOS application
NSString *strUrl = [NSString stringWithFormat:#"http://www.google.com/finance/info?q=NSE:MARUTI"];
NSURL *url = [NSURL URLWithString:strUrl];
NSData *stockData = [NSData dataWithContentsOfURL:url];
NSError *error;
NSMutableArray *arrStock = (NSMutableArray*)[NSJSONSerialization JSONObjectWithData:stockData options:kNilOptions error:&error];
The link returns an array but I am getting an empty array. Can anyone help please

The returned string is not valid JSON because it seems to begin with "// ".
Two things would help with debugging this:
When nil is returned examine (NSLog()) the error return.
NSLog(#"error: %#", error.localizedDescription); returns:
error: The data couldn’t be read because it isn’t in the correct format.
NSLog the returned data.
NSLog(#"data : %#", stockData);
data : <0a2f2f20 5b0a7b0a ...
Notice the leading "0a2f2f20".
or
NSLog(#"data as string: %#", [[NSString alloc] initWithData:stockData encoding:NSUTF8StringEncoding]);
data as string:
// [
{
"id": "7152373"
,"t" : "MARUTI"
Notice the leading "// " which is preceeded with newline character that is not obvious which is why I prefer the hex representation.

Related

Reading JSON file from dropbox iOS

I have a scenario where app reads file from server (dropbox) and checks version. If new version is available then download the app.
I'm trying to read file from link but getting null after JSON parsing.
NSError *error;
NSString *strFileContent = [NSString stringWithContentsOfURL:[NSURL URLWithString:#"https://www.dropbox.com/s/22mm417fxdqdn8c/FileStructure.txt?dl=0"]
encoding:NSUTF8StringEncoding
error:&error];
if(!error) { //Handle error
// NSLog(#"strFileContent: %#",strFileContent);
NSData *data = [strFileContent dataUsingEncoding:NSUTF8StringEncoding];
id json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
NSLog(#"json : %#",[json description]);
}
else
NSLog(#"Error in reading!");
}
Any alternative to DropBox?
There is a way, I find it quite ugly, but still.
First issue, as mentioned by other: yourURLEtcdl=1.
Second big issue, the file is a rtf file, not a JSON object.
So, since there is a way going with RTF => NSAttributedString => NSString => "JSON" => Get your wanted value, here is what you could do:
NSError *error;
NSURL *url = [NSURL URLWithString:#"https://www.dropbox.com/s/22mm417fxdqdn8c/FileStructure.txt?dl=1"];
NSString *strFileContent = [NSString stringWithContentsOfURL:url
encoding:NSUTF8StringEncoding
error:&error];
NSLog(#"strFileContent: %#", strFileContent);
if(!error)
{
NSError *rtfError;
NSAttributedString *attributedString = [[NSAttributedString alloc] initWithData:[strFileContent dataUsingEncoding:NSUTF8StringEncoding]
options:#{NSDocumentTypeDocumentAttribute:NSRTFTextDocumentType} documentAttributes:nil
error:&rtfError];
if (rtfError)
{
NSLog(#"RTFError: %#", [rtfError localizedDescription]);
}
else
{
NSLog(#"string: %#", [attributedString string]);
NSData *data = [[attributedString string] dataUsingEncoding:NSUTF8StringEncoding];
NSError *jsonError;
NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:&jsonError];
if (jsonError)
{
NSLog(#"JSON Error: %#", [jsonError localizedDescription]);
}
else
{
NSLog(#"JSON: %#", jsonDict);
NSInteger version = [[jsonDict objectForKey:#"Version"] integerValue];
NSLog(#"Version: %ld", (long)version);
}
}
}
else
{
NSLog(#"Error: %#", error);
}
As I said, I don't find these very great, it works, but this solution seems to me quite messy (passing twice with NSData).
That's not a text file containing JSON; it's an RTF file containing JSON. That won't work with NSJSONSerialization:
{\rtf1\ansi\ansicpg1252\cocoartf1347\cocoasubrtf570
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\paperw11900\paperh16840\margl1440\margr1440\vieww10800\viewh8400\viewkind0
\pard\tx566\tx1133\tx1700\tx2267\tx2834\tx3401\tx3968\tx4535\tx5102\tx5669\tx6236\tx6803\pardirnatural
\f0\fs24 \cf0 \{\
"Version": 1.0,\
"ImageList": [\
"Nature.png",\
"Nature-1.png",\
"Ballon.png"\
]\
\}}
You've saved that file using an editor that uses RTF (the default Mac TextEdit ). you'll need to re-save as plain text.
Provided URL is incorrect too. If you need only file contents you have to set dl=1 (last component of url). Like so -
dropbox.com/s/22mm417fxdqdn8c/FileStructure.txt?dl=1

NSJSONSerialization and Emoji

I'm currently trying to POST some JSON containing emojis to a python API. I tried feeding the NSJSONSerialization directly with the string containing the emojis from my UITextField but the serializer crashed with no meaningful explanation.
Afterwards I tried to do some format conversion and ended up with something like this:
NSString *uniText = mytextField.text;
NSData *msgData = [uniText dataUsingEncoding:NSNonLossyASCIIStringEncoding];
NSString *goodMsg = [[NSString alloc] initWithData:msgData encoding:NSUTF8StringEncoding] ;
This basically works except that the resulting UTF-8 is kinda double-"escaped" resulting in the following:
"title":"\\ud83d\\udc8f\\ud83d\\udc8f\\ud83d\\udc8f\\ud83d"
Any suggestions how to fix that?
There are two difficulties:
1. Apple hosed NSString WRT UTF Planes 1 and above, the underlying use
of UTF-16 shows through. An example is that length will return 2 for
one emoji character.
2. Whoever decided to put emoji in Plane 1 was
just being difficult, it is the first use of Plane 1 and a lot of
legacy UTF code does not handle that correctly.
Example code (adapted from #Hot Licks):
Updated with OP emoji
NSString *uniText = #"πŸ’¦πŸ’πŸ‘’πŸ‘’πŸ’¦";
NSDictionary* jsonDict = #{#"title":uniText};
NSData * utf32Data = [uniText dataUsingEncoding:NSUTF32LittleEndianStringEncoding];
NSLog(#"utf32Data: %#", utf32Data);
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJSONObject:jsonDict options:0 error:&error];
if (jsonData == nil) {
NSLog(#"JSON serialization error: %#", error);
}
else {
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"The JSON result is %#", jsonString);
NSLog(#"jsonData: %#", jsonData);
}
NSLog output
utf32Data: a6f40100 8ff40100 52f40100 52f40100 a6f40100
The JSON result is {"title":"πŸ’¦πŸ’πŸ‘’πŸ‘’πŸ’¦"}
jsonData: 7b227469 746c6522 3a22f09f 92a6f09f 928ff09f 9192f09f 9192f09f 92a6227d
Sigh:
NSString* uniText = mytextField.text;
NSDictionary* jsonDict = #{#"title":uniText};
NSError* error = nil;
NSData* jsonData = [NSJSONSerialization dataWithJsonObject:jsonDict options:0 error:&error];
if (jsonData == nil) {
NSLog(#"JSON serialization error: %#", error);
}
else {
NSString* jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(#"The JSON result is %#", jsonString);
}
If myTextField.text is a valid NSString then no other conversions should be required. NSJSONSerialization will provide all necessary "escaping".

XML to JSON conversion in ios

i'm trying to convert a simple xml document in Xcode to JSON. The problem is keep returning nil.
This is my code:
NSURL *url = [[NSURL alloc] initFileURLWithPath:#"http://www.w3schools.com/xml/note.xml"];
NSData *xmlData = [[NSData alloc] initWithContentsOfURL:url];
NSError *parseError = nil;
NSDictionary *xmlDictionary = [XMLReader dictionaryForXMLData:xmlData error:&parseError];
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:xmlDictionary
options:NSJSONWritingPrettyPrinted
error:&error];
NSLog(#"%#", jsonData);
Error message:
[NSJSONSerialization dataWithJSONObject:options:error:]: value parameter is nil'
As rmaddy said, try printing parseError. If parseError is Nil, then try printing the xmlDictionary, and check if the dictionary is created correctly.
If xmlDictionary is also Nil, then check the xmlData, which should be fine, in which case the dictionaryForXMLData method must be verified if it checks for any conditions.
Hope I helped.

impossible to parse a url containing "and space in xcode

I'm trying to parse json in a url like:
NSError *error = nil;
NSString *sampleUrl= #"http://xbmc:xbmc#192.168.1.23:8080/jsonrpc?request={\"jsonrpc\":%20\"2.0\",%20\"method\":%20\"VideoLibrary.GetMovies\",%20\"params\":%20{%20\"filter\":%20{\"field\":%20\"playcount\",%20\"operator\":%20\"is\",%20\"value\":%20\"0\"},%20\"limits\":%20{%20\"start\"%20:%200,%20\"end\":%2075%20},%20\"properties\"%20:%20[\"art\",%20\"rating\",%20\"thumbnail\",%20\"playcount\",%20\"file\"],%20\"sort\":%20{%20\"order\":%20\"ascending\",%20\"method\":%20\"label\",%20\"ignorearticle\":%20true%20}%20},%20\"id\":%20\"libMovies\"}";
NSLog(#"%# ",sampleUrl);
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:sampleUrl]];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
but I get an error saying that:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'data parameter is nil'
When I copy my url in my browser: it works!
but not when I tried with xcode
I tried changing the setting "by 22% and eliminating \ : does not work!
how do I proceed?
thanks
The problem is that the string in sampleUrl is not a well formed URL (see RFC 1738).
It contains various characters that are not allowed in URLs, for example { and ". These character have to be percent-escaped before converting to an NSURL.
Where does your URL string really come from?
here is the result that works wonders:
NSString *urlString = [NSString stringWithFormat:#"http://xbmc:xbmc#192.168.1.23:8080/jsonrpc?request={\"jsonrpc\": \"2.0\", \"method\": \"VideoLibrary.GetMovies\", \"params\": { \"filter\": {\"field\": \"playcount\", \"operator\": \"is\", \"value\": \"0\"}, \"limits\": { \"start\" : 0, \"end\": 75 }, \"properties\" : [\"art\", \"rating\", \"thumbnail\", \"playcount\", \"file\"], \"sort\": { \"order\": \"ascending\", \"method\": \"label\", \"ignorearticle\": true } }, \"id\": \"libMovies\"}"];
NSLog(#"%# ",sampleUrl);
NSString *encodedUrl = [urlString stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding];
NSURL *url = [[NSURL alloc] initWithString:encodedUrl];
NSData *jsonData = [NSData dataWithContentsOfURL:[NSURL URLWithString:encodedUrl]];
id jsonObjects = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
Thank you to you all for the help;)

Json Parsing Failed

I am creating a simple Login page. In my project I want to parse the json string. But it gives me following error.
-JSONValue failed. Error trace is: (
"Error Domain=org.brautaset.JSON.ErrorDomain Code=4
\"Valid fragment, but not JSON\"
UserInfo=0xa6e70a0 {NSLocalizedDescription=Valid fragment, but not JSON}"
In my code if I am putting another json string than it is working. And also my original json string is giving me the data in browser. So what to do?
My Code is:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://dev.bevbucks.com/gbs/api.json/token?user=rverma#prismetric.com&pwd=verma!pris"]];
NSURLResponse *response = nil;
NSError *error = nil;
//getting the data
NSData *newData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
//json parse
NSString *responseString = [[NSString alloc] initWithData:newData encoding:NSUTF8StringEncoding];
NSDictionary *jsonObject = [responseString JSONValue];
NSLog(#"type : %#", jsonObject );
The returned string:
"60ee094456b6fc03f386af50c443b471"
Isn't valid JSON, and should at least be:
[ "60ee094456b6fc03f386af50c443b471" ]
So there is a bug in the server, and not your code. If you cannot get this bug fixed then you're going to have to workaround it.
From JSON.org:
JSON is built on two structures:
A collection of name/value pairs. In various languages, this is
realized as an object, record, struct, dictionary, hash table, keyed
list, or associative array.
An ordered list of values. In most
languages, this is realized as an array, vector, list, or sequence.

Resources