JSON Parsing Error in ios - objective-c

I want to fetch some data from some url and print result in nslog.
I am passing URl and want to fetch result in log only.
I have used this code :
-(void)GETJSONDATA
{
NSString*lu=#"tmp";
NSString *requestString = [[NSString alloc]init];
// [[NSUserDefaults standardUserDefaults] setValue:nil forKey:#"WRONGANSWER"];
NSLog(#"request string:%#",requestString);
NSData *requestData = [NSData dataWithBytes: [requestString UTF8String] length: [requestString length]];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:
[NSURL URLWithString: #"http://assessments.tlisc.org.au/webservices/questions/getbytaskpart.php?jsoncallback=?&token=1726204214321678|xTAieBBJoDaWmBsG1stxfq4zLO4&taskpartid=1"]];
NSString *postLength = [NSString stringWithFormat:#"%d", [requestData length]];
[request setHTTPMethod: #"POST"];
[request setValue:postLength forHTTPHeaderField:#"Content-Length"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
[request setHTTPBody:requestData];
NSError *respError = nil;
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: &respError ];
if (respError)
{
// NSString *msg = [NSString stringWithFormat:#"Connection failed! Error - %# %#",
// [respError localizedDescription],
// [[respError userInfo] objectForKey:NSURLErrorFailingURLStringErrorKey]];
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:#"Test" message:#"check your network connection" delegate:self cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alertView show];
}
else
{
NSString *responseString = [[NSString alloc] initWithData:returnData encoding: NSUTF8StringEncoding];
NSLog(#"Resp : %#",responseString);
NSDictionary *results = [responseString JSONValue];
NSLog(#"results=%#",results);
}
}
It is showing me this error :
-JSONValue failed. Error trace is: (
"Error Domain=org.brautaset.JSON.ErrorDomain Code=11 \"Unexpected end of string\" UserInfo=0x6a42be0 {NSLocalizedDescription=Unexpected end of string}"
Can anybody point me error?
In response string , it is showing null value.
I don't know the actual error.
it is working fine in browser but when I parse it it is showing this error....Is there anyway through which I can modify the url and get result ...i have checked my code with different url.and it is working proper..

I think I was using the same library as you're using here, and for some unexplained reason it just failed on a particular google api, sometimes getting results but usually failing. There appeared to be nothing wrong with the code.
In the end I went with the inbuilt NSJSONSerialization ( http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSJSONSerialization_Class/Reference/Reference.html ) object and it hasn't failed since. I wasn't even aware there was JSON support built in (from iOS5 apparently).
I ran the two calls and processed them side by side, the external library continually failed. The internal methods worked fine.
Since I'm a beginner and the docs (above) don't really help me a lot, I used this tutorial http://www.raywenderlich.com/5492/working-with-json-in-ios-5 to get my head around it

As the error told you: the incoming JSON is not well-formed. Making a simple GET request to the URL you are using, I'm getting a JSON that is malformed, i.e. it is not valid JSON. I guess posting data to this URL returns the same format with actual data in it (not null).
Making use of a simple JSON Validator, I'm getting this
Parse error on line 5: ... "Description": "\n\tQuestion Numbe
-----------------------^ Expecting 'STRING', 'NUMBER', 'NULL', 'TRUE', 'FALSE', '{', '['

Check your url in a browser. See the result. Your result's Structure should be like the same as JSON. if there is any other extra word in start of the json means. you should check your php code.

You have got HTML tags within your strings. Paragraph marks like
<p> and </p>
And these are not properly escaped. However, I do not know by hard wether the less than sign and greater than sign need to be escaped in JSON but apparently they are creating the issue.
Using google I find statements for both. However, some site suggests escaping < with \u003c and > with \u003e. that should do the trick.
I tried to validate the output from
http://assessments.tlisc.org.au/webservices/questions/getbytaskpart.php?jsoncallback=?&token=1726204214321678|xTAieBBJoDaWmBsG1stxfq4zLO4&taskpartid=1
It seems to be valid though if the <p> and </p> ist not interpreted by the bowser. (I was lookint to the "page source").
However, when escaped the string is still valid and encodes to the same result.
If this is not your issue, then please provide the output of your
NSLog(#"Resp : %#",responseString);

Related

Rails params not being constructed correctly

I have a strange issue.
I have tried a lot of different things to reproduce the issue but it has not been possible. The error shows up thanks to exception_notification.
I am sending a NSDictionary to the backend, and instead of being parsed as a dictionary, this is what I get (on the rails side):
* Parameters : {"{\"facebook_id\":\"\",\"city\":\"\",\"account_type\":\"email\",\"poll_reminder\":\"0\",\"last_name\":\"\",\"picture_url\":\"\",\"email\":\"\",
\"birthday\":\"\",\"users_value_categories_attributes\":"=>{"{\"value_category_id\":25},{\"value_category_id\":24},
{\"value_category_id\":21},{\"value_id\":24,\"priority\":14},{\"value_id\":21,\"priority\":15},
{\"value_id\":58,\"priority\":16},
{\"value_id\":8,\"priority\":17},{\"value_id\":9,\"priority\":18},{\"value_id\":41,\"priority\":19},
{\"value_id\":27,\"priority\":20}"=>{",\"first_name\":\"\"}"
=>nil}}}}}
It is dictionary where the only key is my serialized dictionary!
This is the error on the rails side:
An ActiveRecord::UnknownAttributeError occurred in #:
unknown attribute: {"facebook_id":"","city":"","account_type":"email","poll_reminder":"0","last_name":"","picture_url":"","email":"","birthday":"",":...........
app/api/v2/resources/example_business_api.rb:6:in `block in <class:ExampleBusinessApi>'
params hash is like:
{"<MY SERIALIZED DICTIONARY" => nil }
instead of being the dictionary itself.
The relevant code in iOS is:
request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:urlString]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[self getHTTPBodyForUser:theUser]];
getHTTPBodyForUser is the following:
+ (NSData *)getHTTPBodyForUser:(User *)user {
// Load a tmp dictionary using user variable
....
// The tmp dictionary is totally fine
NSError *error;
NSData *postdata = [NSJSONSerialization dataWithJSONObject:tmp options:0 error:&error];
return postdata;
}
The weird part is that just some users are having the error.....
Any help?

Replace " in string with \"

I am trying to send a string to the server. I encode it and set it as the body of an HTTP request using
[request setHTTPBody:[body dataUsingEncoding:NSUTF8StringEncoding]];
Where body is the string.It has to be in json format.
For example
body = [NSString stringWithFormat:#"{\"emailBody\":\"%#\"}",string] ;
should be valid
But i accept string from user and it may contain double quotes.Therefore i have to escape double quotes(") in it.
For example if want to send just one "
{\"emailBody\":\"\\\"\"}
(harddcoded) returns positive response from server.
So i would like to create such a string from the original string.I tried the following
string = [string stringByReplacingOccurencesOfString:#"\"" withString:#"\\\\\""];
But it did not work.I got \" in my test email.Thats as far as i have been able to get.
Am I taking the right approach ??I would appreciate it if someone would point me in the right direction.Thanks
You should generate your JSON directly from a dictionary. That'll take care of all the encoding automatically for you:
NSDictionary *body = #{#"emailBody": string};
NSError *error;
NSData *jsonData = [NSJSONSerialization dataWithJSONObject:body options:0 error:&error];
if (!jsonData) {
NSLog(#"Got an error: %#", error);
} else {
NSString *jsonString = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
[request setHTTPBody:jsonString];
}

JSON Payload doesnt seem to be sending

My problem I'm pretty positive is simple, I must just be missing something.. just not sure what.
I can send GET and POST for granular elements (this=that kind of stuff), but a web service call I need to send data too, takes a raw JSON block, with no "key"
Heres the method I wrote:
-(NSData *)execute {
// Smart Chooser ?
if(PostData.count >0 || Payload != nil)
[self setMethod:UPLINK_METHOD_POST];
else
[self setMethod:UPLINK_METHOD_GET];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:self.connectionUrl
cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData
timeoutInterval:10];
if([UPLINK_METHOD_GET isEqualToString:self.connectionMethod])
[request setHTTPMethod:#"GET"];
else
[request setHTTPMethod:#"POST"];
NSString *gData = [self compileGetData];
NSString *pData = [self compilePostData];
// if we have get data, set it into the URL string
if(GetData.count > 0) {
[self setURLWithString:[[self.connectionUrl absoluteString] stringByAppendingString:[#"?" stringByAppendingString:gData]]];
[request setURL:self.connectionUrl];
}
// if we have post data, set it in the body
if(PostData.count > 0) {
const char *bytes = [[NSString stringWithString:pData] UTF8String];
[request setHTTPBody:[NSData dataWithBytes:bytes length:strlen(bytes)]];
}
// Override any post data if a payload is already defined.
if(Payload != nil) {
[request setHTTPBody:[Payload dataUsingEncoding:NSUTF8StringEncoding]];
}
NSLog(#"URL : %#", request.URL);
NSURLResponse *response;
NSError *err;
NSData *responseData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
if(err != nil)
NSLog(#"here was an error: %#", err);
return responseData;
}
-(NSDictionary *)executeAsJSON
{
NSData *responseData = [self execute];
NSError *e;
return [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableContainers error:&e];
}
Ok SO, the way this thing works, is that it automatically sets whether the request is POST or GET depending on the data provided in the GetData, PostData, and Payload vars.
The request is GET by default, but turns into POST if PostData or Payload have anything in them.
The compileGetData and compilePostData mostly just bring back formatted strings with arrays of information combined, nothing special there.
But thats not where the problem is.
See, "Payload" overrides anything "PostData" had in it. If you had provided PostData elements into the class, it would just be overridden by a provided Payload if that does exist.
I needed to provide this to demonstrate the "workarea" as it exists right now, its not linearly provided information.
This is the area of interest:
// Override any post data if a payload is already defined.
if(Payload != nil) {
//const char *plbytes = [[NSString stringWithString:Payload] UTF8String]; // this didn't work
[request setHTTPBody:[Payload dataUsingEncoding:NSUTF8StringEncoding]]; // inline, doesn't work either
}
When I say "doesnt work", what I mean is, im getting back an error JSON array from the webservice that basically means "hey, wheres the payload?". If the request is not POST it comes back as a general error, so thats all working, the URL is then obviously correct.
I've used RESTConsole for Chrome to test the webservice to make sure its working properly, and it does.
I've also checked through the debugger the exact payload im sending, i copy+pasted that into RESTConsole, and it works there.
I'm.. honestly at a loss here...
Try using a web proxy like Charles or Wireshark (I personally preferr Charles due to it's ease of use, it's a 30-day trial though) and monitor the request you make from RESTConsole and the one you make from your app and see if they look the same.
Check any headers, line returns and anything else that looks different.
That's the best I can think of to start with

EXC_BAD_ACCESS on NSLog unless the NSString is manipulated and printed first

I'm trying to get a feel for objective C, so I wrote the code below to try to print the contents of a web page:
id url = [NSURL URLWithString:#"http://www.google.com"];
NSURLRequest* req = [NSURLRequest requestWithURL:url];
NSURLResponse* resp = [NSURLResponse new];
NSURLConnection* conn = [NSURLConnection new];
NSError* error = nil;
NSData* data = [NSURLConnection sendSynchronousRequest:req returningResponse:&resp error:&error];
NSString* html = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
// printf([[html substringToIndex:50] cString]);
NSLog(html);
when I run this as-is, I get EXC_BAD_ACCESS on the NSLog line. When I uncomment the second-last line it works. If I change the printf to an assignment it stops working again. I'm clearly missing something here about how the memory model works, but it seems like the commented out line shouldn't make any difference since it's creating a new string and it really seems like printf vs an assignment shouldn't make a difference. In the Xcode debugger when the program crashes I can see that html does contain the HTML string I wanted to print.
try NSLog(#"%#", html) instead of just NSLog (html)

Passing html parameters to server odd problem

I am having a weird problem with sending data back to my server. This is the code I am using:
NSString *theURL =[NSString stringWithFormat:#"http://www.xxx.com/confirm.asp?theID=%#&theName=%#&empID=%#&theComp=%#", theConfirmNum, tmpNBUserRow.userName, labelTxt.text, theID];
NSLog(#"%#,%#,%#,%#", theConfirmNum, tmpNBUserRow.userName, labelTxt.text, theID);
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease];
[request setURL:[NSURL URLWithString:theURL]];
[request setHTTPMethod:#"POST"];
NSError *error;
NSURLResponse *response;
NSData *urlData=[NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];
NSString *data=[[NSString alloc]initWithData:urlData encoding:NSUTF8StringEncoding];
if ([data isEqualToString:#"Done"])
I can run the code from the browser and it works just fine using the data i got from the NSLog output. The NSLog output for each value is correct. But for some reason when i put a break on:
if ([data isEqualToString:#"Done"])
...it has no return value. I checked each value for what it was sending (and again, it was correct in the NSLog output) and I found that the value "theID" said "Out of scope". Although, again, the NSLog had the value in it correctly?
So I searched the forum and found a simular problem. I took their advice and added "RETAIN" to the "theID" value like so:
theID = [customObjInstance TID];
[theID retain];
However, that did not solve the issue...
Here is the console NSLog output:
[Session started at 2010-04-11 01:31:50 -0400.]
wait_fences: failed to receive reply: 10004003
wait_fences: failed to receive reply: 10004003
nbTxt(5952,0xa0937500) malloc: *** error for object 0x3c0ebc0: double free
*** set a breakpoint in malloc_error_break to debug
2010-04-11 01:32:12.270 nbTxt[5952:207] 5122,Rob S.,5122,NB010203
The NSLog values I am sending is the last line "5122,Rob S.,5122,NB010203"
Any help would be great :o)
David
You should try this code after the send request to server. I think this should resolve your problem.
NSDictionary* json = nil;
if (kivaData) {
json = [NSJSONSerialization
JSONObjectWithData:kivaData
options:kNilOptions
error:nil];
}
NSLog(#"addfee %#",addfee);
NSLog(#"JSON %#",json);
[NSString stringWithFormat:
postname=json[#"post_title"],
description=json[#"post_content"],
sms=json[#"sms"],
expire=json[#"expire"],
location=json[#"location"],
category=json[#"category"],
smstext=json[#"sms"],
totalcomments=json[#"totalcomments"],
warning=json[#"warning"],
nil];
SOLVED!!!
It was all because of the space between the name "Rob S.". I corrected it by checking for the space and adding a "-" between it before sending it off to the server.
NSString *tempUN = tmpNBUserRow.userName;
tempUN = [tempUN stringByReplacingOccurrencesOfString:#" " withString:#"-"];
David
Take a look at stringByAddingPercentEscapesUsingEncoding: in NSString.