parsing json - reached max depth - iphone

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.

Related

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

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)

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.

JSON returning null

I'm having a bit of trouble parsing some returned JSON. I'm fairly new to working with JSON. I'm trying to get the company name from the first JSON array element. I have a feeling that I'm confusing the use of NSMutabeArray and NSMutableDictionary. What I get is null. Any idea what I'm doing wrong?
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];
NSString* companyName = [[json objectAtIndex:0] objectForKey:#"name"] ; //Where I need some help
NSLog(#"we got %#", companyName);
Load that url in your browser. Looks like google is prefixing the JSON with //. I think NSJSONSerialization is tripping on that. Try this
NSRange range = NSMakeRange(2, [data length] - 3);
NSData *noPrefix = [data subdataWithRange:range];
Then send that to the parser.
You put in an error object, but you never looked at it. If you had, you would see that the data is corrupted:
Error Domain = NSCocoaErrorDomain Code = 3840 "The data couldn’t be read because it has been corrupted." (Invalid value around character 1.) UserInfo = 0x10030a8f0 { NSDebugDescription = Invalid value around character 1. }
I changed the value of the options parameter to see this error. I have
NSMutableArray* json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers |NSJSONReadingAllowFragments error:&error];

Fetch XML of Distance Matrix API (google) on iPhone

I'm trying to fetch the XML data from a query to the api without success...
I'm doing this:
[...]
NSURL *googleAPIurl = [NSURL URLWithString:#"http://maps.googleapis.com/maps/api/distancematrix/xml?origins=28.124822,-15.430006&destinations=28.126953,-15.429874|28.072056,-15.416574|28.103186,-15.417665|28.127916,-15.625403|28.099125,-15.418365|28.107740,-15.454050|28.050825,-15.454066|28.051640,-15.454104|28.101788,-15.423592|28.113750,-15.446980|28.098871,-15.420730|28.098217,-15.449371|28.083364,-15.418172&mode=driving&sensor=false"];
NSData *xmlData = [NSData dataWithContentsOfURL:googleAPIurl];
NSError *error;
GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error];
if (xmlDocument == nil)
{
NSLog(#"NIL XML");
}
[...]
I'm ALWAYS getting a nil XML. NSData is always nil. I don't know what is happening with this. If I use a url with one destination only it works, but not for more than one. Also, I'm using the same method to retrieve xml with google places api with no problems. This is driving me crazy...
Please point me in the right direction.
Thanks in advance.
I suggested replacing all of the '|' with '%7C'
Turns out this is the more proper method to cover all of these character encoding issues:
NSURL *googleAPIurl = [NSURL URLWithString:[distancesURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]];

Not able to hit server with sendSynchronous method

I am using a synchronous request to send an image as hexa string to a server. I am not able to hit the server if I send hexa string of images of resolution 200x150 but I am able to get response from server if send the same image at a lower resolution like 100x75.
NSMutableString *urlString = [NSMutableString stringWithString:#"http://xxxxxx:8080/GeoLocationSave/ReceiveImage"];
UIImage *sample = [UIImage imageNamed:#"ip_addphoto_100x75#2x.png"];
NSData *imgData = UIImagePNGRepresentation(sample);
[urlString appendString:#"?image="];
[urlString appendString:hexImage];
NSError *error;
error=nil;
NSURLResponse *response;
response=nil;
NSURL *url = [NSURL URLWithString:urlString];
NSData *urlData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:url] returningResponse:&response error:&error];
The length of urlData is 0 for a higher resolution image. Log value of imageData for both images are perfect. I don't see any entry point log in server for higher resolution image.
NSData *urlData = [NSURLConnection sendSynchronousRequest:[NSURLRequest requestWithURL:urlString]
returningResponse:&response
error:&error];
NSString *result = [[NSString alloc] initWithData:urlData
encoding:NSUTF8StringEncoding];
NSLog(#"return: %#" , result); // to see the response
You're using a URL here with [NSURLRequest requestWithURL:url], but above you use urlString. Where do you set URL equal to something?
Hi guys i found what mistake i was making. I was too ridiculous to push data as large as 8000 bytes through HTTP Get method. I noted that if the url length is greater than 8000 bytes it doesn't hit the server. So i just moved over to HTTP POST method as in case if image taken through camera (which can can easily get past the 8000 bytes length) is to be sent to server it wouldn't hit the server.