How to parse json data with "var abcd =" header - iphone

I'm having problem with parsing json data file on iOS.
This is a sample from the data.json file:
var devs = [
{
"ident":"1",
"firstname":"Jan",
"lastname":"Kowalski",
"img":"http://www.placekitten.com/125/125",
"tech":"iOS, HTML5, CSS, RWD",
"github":"placeholder",
"opensource":"1",
"twitter":"placeholder"
},
{
"ident":"2",
"firstname":"WacĹaw",
"lastname":"GÄsior",
"img":"http://www.placekitten.com/124/125",
"tech":"Android, Java, Node.js",
"github":"GÄsiorBKR",
"twitter":"wacek5565"
},
and so on.
With "normal" json files I use:
NSURLResponse *response;
NSError *myError;
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:[NSURL URLWithString:#"http://somerailsapplication/posts.json"] cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30.0f];
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&myError];
NSDictionary *res = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&myError];
Unfortunately this solution doesn't work in this case.
Is there any chance to get this working without searching for specific string "var dev=[" and the last "]" in the downloaded data?

The response is javascript, not JSON, so you won't be able to use a JSON parser directly. If you can't change the server output, the easiest thing would be to strip the beginning and end of the data, as you suggested. You could also embed the response in an HTML template and evaluate it in a webview, but that seems like a lot of more work.

Starting at the point where you've got the data:
NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&myError];
NSMutableString *dataAsString = [[NSMutableString alloc] initWithData:data encoding:NSUTF8StringEncoding];
[dataAsString deleteCharactersInRange:NSMakeRange(0, 11)];
data = [dataAsString dataUsingEncoding:NSUTF8StringEncoding];
NSArray *res = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:&myError];
This turns the data into a string, removes the first 11 characters, turns it back into data, and then parses it as normal. (I've changed it to NSArray since your data is in an array)

Related

How do I post images to reddit in iOS / Objective C?

I am trying to post an image to reddit; however, I only kind of know what I am doing. I am using objective c for my iphone app.
Prior to the code listed below I obtain a modhash and cookie by logging in prior to the upload and use NSLog to determine that I truly am receiving them. Then I use a JSON Parser to separate them into separate variables.
I was not sure what all of the POST argument values were supposed to be so I kind of guessed. The necessary arguments are uh, file, formid, header, ing_type, name, and sponsor.
The documentation for reddit api is http://www.reddit.com/dev/api I believe that I want to use the POST /api/upload_sr_img method...
NSURL *url = [NSURL URLWithString:#"http://www.reddit.com/api/upload_sr_img"];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:#"POST"];
NSString *httpBody = [NSString stringWithFormat:#"?uh=%#&file=%#&formid=''header=%#&img_type=%#&name=%#&sponsor=%#",modhash,UIImagePNGRepresentation(self.memeImage.image),#"test",#"png",#"Drew",#"Drew'sApp"];
[request setHTTPBody:[httpBody dataUsingEncoding:NSASCIIStringEncoding]];
NSURLResponse *response = NULL;
NSError *imgError = NULL;
NSData *result = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&imgError];
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingMutableContainers error:nil];
NSDictionary *responseJson = [json valueForKey:#"json"];
NSLog(#"response is: %#",response);
NSLog(#"imgError is: %#",imgError);
NSLog(#"result is: %#",result);
NSLog(#"json is: %#",json);
NSLog(#"responseJson is: %#",responseJson);
Could use any help I can get.
Also, I was not sure if I needed to send a content-type or even what it would be.
Thanks for your help.
Check this library: https://github.com/MattFoley/MFRedditPostController
You can use the provided UI or create your own.

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

parsing json - reached max depth

I want to parse the comments of a reddit post with over 500 comments.
For example this one: http://www.reddit.com/comments/xu11o
The json url is: http://www.reddit.com/comments/xu11o.json
In am using SBJson to achieve this.
When I try to get a NSArray with this code:
NSString* response = [request responseString];
NSArray* responseArray = [response JSONValue];
I get this error message: -JSONValue failed. Error is: Input depth exceeds max depth of 32
Changing the depth to a higher number of for example 100 makes my app crash.
If the reddit post has only 20 comments I get the NSArray and can successfully display them.
What do I have to change to get the NSArray?
Have you tried Apple's NSJSONSerialization JSON parsing library? It works.
NSString *urlString = #"http://www.reddit.com/comments/xu11o.json";
NSURL *url = [NSURL URLWithString:urlString];
NSURLResponse *response = nil;
NSError *error = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:
[NSURLRequest requestWithURL:url]
returningResponse:&response
error:&error];
id jsonObj = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
// Do something with jsonObj which is an array.
Just make sure you switch your download code to asynchronous before shipping.
Best regards.
Try my JSON parser library, it has no such limitation:
http://github.com/H2CO3/CarbonateJSON
This "limitation" of SBJsonParser is a security feature, protecting you from presumed malicious JSON. The limit is configurable through the maxDepth property. The default is 32, as you've found. You can change it to any integer value you want, or turn the max depth check off by setting it to 0.
I had the same issue with sbjson. Changing the maxDepth (SBJsonParser.m)to 128 solved the problem.

Removing // from NSMutableArray

When I NSLog the contents of an NSMutableArray I get null. I believe I know what the issue is.
I'm having a bit of trouble trying to figure out how to remove "//" at the beginning of this JSON output. If you load http://www.google.com/finance/info?infotype=infoquoteall&q=AAPL,C into your browser you'll see the "//" at the beginning. I believe that the "//" is what is causing the array to return null. How could I go about removing the two dashes? Below is I have what I've done thus far...
NSString *url = #"http://www.google.com/finance/info?infotype=infoquoteall&q=C,JPM,AIG,AAPL";
NSData* data = [NSData dataWithContentsOfURL:
[NSURL URLWithString: url]];
//parse out the json data
NSError* error;
NSMutableArray* json = [NSJSONSerialization
JSONObjectWithData:data //1
options:kNilOptions
error:&error];
NSLog(#"json is %#", json); //returns "json is (null)"
You can try this:
NSData *newData = [data subdataWithRange:NSMakeRange(4, [data length] -4)];
This gets rid of the first four characters. There was a control character the two slashes and a space before the first "[", and this gets rid of those. I tried this but the data still had a flaw in it further on.

iPhone encoding of non latin characters

I am trying to parse a JSON response of a GET request. When the characters, are latin no problem.
However when they are not latin the message doesn't come out correctly. I tried greek and instead of "πανος" i get "& pi; & alpha; & nu; & omicron; & sigmaf;"
The code I use for parsing the response is:
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSLog(#"response %#", responseString);
// array from the JSON string
NSArray *results = [responseString JSONValue];
When I try to read the response from a website using ajax, everything is fine. The same applies when trying to send a GET request to the application servers with data from iphone. So when i transmit data to the server and read it from the website everything is fine. When i try to show the same data in the app, "Houston we have a problem".
Any clues?
EDIT: To avoid misunderstandings, it's not an issue of HTML, I just point out that for some readon utf-8 characters here are encoded correctly and automatically eg. "&pi" will be converted to "π", however objective c doesn't seem to do this on its own
There is a confusion I think.
π is an HTML entity which is unrelated to text encoding like UTF8 / Latin.
Read wikipedia for details about...
You need a parser to decode these entities like the one previously mentioned by Chiefly Izzy:
NSString+HTML category and method stringByReplacingHTMLEntities
Look at Cocoanetics NSString+HTML category and method stringByReplacingHTMLEntities method. You can find it at:
https://github.com/Cocoanetics/NSAttributedString-Additions-for-HTML/blob/master/Classes/NSString%2BHTML.m
Here's a pretty decent list of lot of HTML entities and their corresponding unicode characters.
Try to use this snippet of code:
NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
NSString *decodedString = [NSString stringWithUTF8String:[responseString cStringUsingEncoding:[NSString defaultCStringEncoding]]];
NSLog(#"response %#", decodedString);
// array from the JSON string
NSArray *results = [decodedString JSONValue];
I have faced the same problem, but I solved it by changing the JSON parser. I have started using the SBJSONParser, and now I am getting the appropriate results. This is the code snippet, I have used
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
SBJSON *parser=[[SBJSON alloc]init];
NSArray *JSONData = (NSArray*)[parser objectWithString:returnString error:nil];