ASIFormDataRequest JSON encoding issues - json

I seem to have run into a rather trivia issue that I can't figure out. I am using ASIFormDataRequest for interacting with my Ruby on Rails app. I have a REST API that accepts a User object. I am using JSONKit to get the JSONString from a NSDictionary.
However, when I do a
[request setPostValue:[userObj JSONString] forKey:#"user"];
The request on the server side ends up escaping the quotes. Basically,
{"password":"hello","name":"user","email":"user#foo.com"}
TO
"{\"password\":\"hello\",\"name\":\"user\",\"email\":\"user#foo.com\"}"
This ends up confusing rails and it complains of an invalid object. Can I force ASIFormDataRequest to not escape the quotes? I understand this might be an issue with the JSONString itself but I can't figure out a good solution here.
Thanks

This is what worked for me:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:url];
NSDictionary* inner = [[NSDictionary alloc] initWithObjectsAndKeys:username, #"login",password, #"password", nil];
NSDictionary* user = [[NSDictionary alloc] initWithObjectsAndKeys:inner, #"user", nil];
NSMutableData *requestBody = [[NSMutableData alloc] initWithData:[[user JSONString] dataUsingEncoding:NSUTF8StringEncoding]];
[request addRequestHeader:#"Content-Type" value:#"application/json; encoding=utf-8"];
[request addRequestHeader:#"Accept" value:#"application/json"];
[request setRequestMethod:#"POST"];
[request setPostBody:requestBody];
[request startAsynchronous];

It's not usual to mix ASIFormDataRequest and JSON - normally people encode things in the HTML form data format or they encode in JSON format. Not both!
Could you consider using pure JSON in this case? It might well make your life easier. Basically you would use an ASIHTTPRequest instead of an ASIFormDataRequest, and set it up like this:
NSString *postData = [userObj JSONString];
[request addRequestHeader: #"Content-Type" value: #"application/json; charset=utf-8"];
[request appendPostData:[postData dataUsingEncoding:NSUTF8StringEncoding]];
Aside from that, it's not really clear why it's going wrong - can you use something like wireshark to capture the raw text of the http request you're sending and add that to your question?
How are you extracting the JSON data from the form data on the Ruby side?

Related

HTML truncated because of NULL character

I am downloading HTML from a server (one that I cannot control), and sometimes the response will include a NULL character in the middle somewhere. Because of this, the response is being truncated at that point. How do I remove that NULL character and prevent it from being truncated? Here's the code I'm using:
ASIHTTPRequest *_request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:[NSString stringWithFormat:#"%#%#", [DEFAULTS objectForKey:#"gradespeed_url"], #"ParentStudentGrades.aspx"]]];
__weak ASIHTTPRequest *request = _request;
[request setAllowCompressedResponse:NO];
[request setValidatesSecureCertificate:NO];
[request setCompletionBlock:^{
NSData *response_data = [request responseData];
NSString *response_string = [request responseString];
}];
The NSString is truncated, but maybe it's possible to manipulate the NSData? Please advise.
Don't rely on [request responseString] do your own conversion from [request responseData] handling the null as appropriate.
Or examine the ASIHTTP code to find out exactly what is happening.
The solution I discovered was actually quite simple. I just needed to add the following code to remove the random NULL characters:
response_string = [response_string stringByReplacingOccurrencesOfString:#"\0" withString:#""];

Converting URLWithString to NSURLConnection

I am new to iOS development and I am trying to retrieve some data from server.
I have used:
NSData *jsonDataString = [[NSString stringWithContentsOfURL:[NSURL URLWithString:url] encoding:NSUTF8StringEncoding error: nil] dataUsingEncoding:NSUTF8StringEncoding];
which is freezing my app's UI. I put it dispatch but this causes other issues.
How to convert this one to NSRULConnection which will reply NSData like URLWithString?
Thank you
I found the solution. I was dispatching [self function1[self function2[self function3]]]; where the function3 was the json request. After dispatching only function3 the result was fine

How to pass an HTML string in a Query String in IOS

I have a simple IOS application that I created for consultants where I work. It has a custom keyboard with notation that they use that includes superscript and subscript characters. The easiest way that I found to handle those characters was using HTML and a WebView, which works just fine.
I am now attempting to send this information to a web application that will insert it into a SQL database. Sending all of the other information works just fine, until I get to the transcript with HTML in it. I am encoding each of the values that I send through the query string with stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding but the query string fails when HTML elements are included. I believe this is due to the / that is not removed during the escape encoding. For example the HTML break tag becomes %3Cbr%20/%3E. So the < > and space are replaced, but not the /.
Should I be using a different method? Is there an easy way to send HTML over Query String? Am I correct that the / character is what is breaking my query string?
Here is the code I have now:
NSString *datePE =[dateString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *studentPE =[student stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *teacherPE =[teacher stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *transcriberPE =[transcriber stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *vrPE =[vrTextField.text stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *totalTimePE =[totalTimeString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *transcriptPE =[transcriptString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
parameters = [NSString stringWithFormat:#"dateQS=%#&studentQS=%#&teacherQS=%#&transcriberQS=%#&vrQS=%#&totalTimeQS=%#&transcriptQS=%#",datePE ,studentPE,teacherPE,transcriberPE,vrPE,totalTimePE, transcriptPE];
request = [NSMutableURLRequest
requestWithURL:[NSURL URLWithString:#"http://server.domain.net/folder/subfolder/Default.aspx?"]];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[parameters dataUsingEncoding:NSUTF8StringEncoding]];
connection = [[NSURLConnection alloc] initWithRequest:request
delegate:self
startImmediately:YES];

ios5: Sending JSON data from the iPhone to REST using POST

I am trying to send data in the JSON format to the REST api. When sending a parameter the web service does not return any data but instead gives the following error:Error parsing JSON: Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (JSON text did not start with array or object and option to allow fragments not set.)
This is because the parameter cannot be read by the web service.
But if I add this parameter directly to the URL the correct results are returned Eg:http://localhost:8080/de.vogella.jersey.final/rest/notes/63056
The following is the code for sending the parameters:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:#"http://localhost:8080/de.vogella.jersey.final/rest/notes/"]];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-Type"];
NSString *postString = #"{\"notes\":\"63056\"}";
NSLog(#"Request: %#", postString);
// NSString *postString = #"";
[request setValue:[NSString stringWithFormat:#"%d",[postString length]] forHTTPHeaderField:#"Content-length"];
[request setHTTPBody:[postString dataUsingEncoding:NSUTF8StringEncoding]];
NSData *returnData = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil ];
NSLog(#"Return Data%#",returnData);
//Getting the task types from the JSON array received
NSMutableArray *jsonArray =[NSJSONSerialization JSONObjectWithData:returnData options:kNilOptions error:&error];
NSLog(#"jsonArray is %#",jsonArray);
taskTypes =[[NSMutableArray alloc]init ];
if (!jsonArray) {
NSLog(#"Error parsing JSON: %#",error);
} else {
for(NSDictionary *taskType in jsonArray) {
[taskTypes addObject:[taskType objectForKey:#"TaskName"]];
}
}
Any suggestions?
Your error "JSON text did not start with array or object and option to allow fragments not set" could mean two things:
You're specifying that you expect the response object to be in JSON format and it is not (for example, this would happen if you're using an AFJSONRequestOperation and the server returns something other than JSON)
Fix: Get a hold of the server code and make sure it returns a valid JSON object
You have not specified that you're okay with receiving something other than JSON
Fix: If you're using AFNetworking, pass in NSJSONReadingAllowFragments to [NSJSONSerialization JSONObjectWithData:options:error:] on your subclass of AFHTTPClient (Shout out to Cocoa error 3840 using JSON (iOS) for this answer).

App is STILL not updating database when string contains spaces

Slowly but surely I think I'm going mad. After getting the solution to my problem and the app now also accepting spaces, it still won't add the data that contains spaces to my mysql database. Here is the code:
NSString *strURL = [NSString stringWithFormat:#"http://www.bbc.com/phpFile.php?number=%#&name=%#&lastname=%#", number, firstName, lastName];
NSString *webStringURl = [strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:strURL]];
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];
NSLog(#"%#", strResult);
NSLog(#"%#", webStringURl);
NSLog even tells me that it does exactly what I tell him to:
ProjectX[4003:15203] http://www.bbc.com/phpFile.php?number=11166&name=Yong%20Wang%20Ding&lastname=Blamblam
It works everytime when the variables do not contain spaces. When I open the php file in my browser and enter the variables by hand (with spaces) it adds them to my database. I have no clue why it refuses to work when doing exactly(?) the same thing with my app.
It doesn't look like you're using webStringURl (sic) anywhere other than in the final NSLog statement. Are you sure you didn't mean to write:
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:webStringURl];
...for the third line?
At the moment, you're calling dataWithContentsOfURL on your unescaped version of the URL (which may still contain spaces).