Objective C HTTP Post Request Parameters Getting Lost Between App and Server - objective-c

I'm trying to send a post request from my iOS app to the server. The request works when using curl:
curl -d "uid=1&type=robbery&x=41.66505&y=-93.73046" http://thawing-ravine-5632.herokuapp.com/sos
And here's the Objective-C code that is making the request:
NSMutableURLRequest *request = [[NSMutableURLRequest alloc]
initWithURL:[NSURL
URLWithString:#"http://thawing-ravine-5632.herokuapp.com/sos"]];
[request setHTTPMethod:#"POST"];
[request setValue:x
forHTTPHeaderField:#"x"];
[request setValue:y
forHTTPHeaderField:#"y"];
[request setValue:type
forHTTPHeaderField:#"type"];
[request setValue:uid
forHTTPHeaderField:#"uid"];
NSURLConnection * postOutput =[[NSURLConnection alloc]
initWithRequest:request
delegate:self];
Finally, didReceiveData Logs the following:
2013-03-31 20:29:32.248 THST Mobile[14720:11c03] connectionDidReceiveData {"student_found":0,"school_found":0,"officer_found":0,"text_sent":0,"uid":0,"x":0.0,"y":0.0,"type":null}
But logging the variables before the request is made shows that they are indeed instantiated in the app prior to making the request. SSHing into the server shows that they are all just either nil or empty strings when the request is received. So something is wrong with my Objective-C code for making the post request - probably with the way I'm setting the parameters?

You're setting the values as headers, not as request's body.
NSString *params = #"x=1&y=bla&z=foo";
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[params dataUsingEncoding:NSUTF8StringEncoding]];

Related

NSURLRequest the request time out

I've a strange problem, I'm working on a project that I've to request from a server, When requesting a URL without parameters using GET method, it works fine and return the desired data, but when using the same code to call the URL and sending a parameters to it, it fail with this error:
error: Error Domain=NSURLErrorDomain Code=-1001 UserInfo=0xed4870 "timed out"
My code is the following:
NSString *param = #"pageNumber=2";
NSURL *url = [NSURL URLWithString:#"http://myWebsite/api/Soccor/"];//When using this, it works fine
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:#"http://myWebsite/api/Soccor?%#", param]];//When using this, it gives me the request time out error.
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
[theRequest addValue:#"application/json;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[theRequest addValue:#"application/json" forHTTPHeaderField:#"Accept"];
[theRequest addValue:msgLength forHTTPHeaderField:#"Content-Length"];
[theRequest setHTTPMethod:#"GET"];
[theRequest setTimeoutInterval:10];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
Any clue why it returns error when sending parameters with the URL?
I would suggest you consider two aspects of the request:
You are not showing us your setting of msgLength, but I would only suggest setting a Content-Length header if you're also using setHTTPBody, in which case you'd set the Content-Length to be the length of the NSData you use as a parameter to setHTTPBody. But this is used with POST requests, not GET requests.
You specify application/json for the Content-Type of the request, but request does not consist of JSON. If you did that because the response is JSON, it should be noted that this header value is for your request, not for the response you expect from the server.

NSURLRequest setValue: forHTTPHeaderField:#"Authorization" not working

I try to make an authenticate call to the twitter API with the Application only Authentication API
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url]
cachePolicy:NSURLRequestReloadIgnoringLocalCacheData
timeoutInterval:20.0];
[request setHTTPMethod:#"POST"];
[request setValue:#"application/x-www-form-urlencoded;charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
[request setValue:#"Some App Name" forHTTPHeaderField:#"User-Agent"];
[request setValue:authValue forHTTPHeaderField:#"Authorization"];
[request setHTTPBody:[#"grant_type=client_credentials" dataUsingEncoding:NSUTF8StringEncoding]];
Interestingly the authValue is not getting set for HTTPHeaderField #"Authorization". Therefor my calls fail of course. All other header fields are set correctly.
I check it by
NSLog(#"Authorization, %#, %#", [request valueForHTTPHeaderField:#"Authorization"], authValue);
which returns #"Authorization, (null), theCorrectStuff
Why is this happening? I should be able to set it right away, or am I missing something?
Thanks for your time and consideration,
Fabian
I had the same issue. Output your authValue, it probably contains new lines. For the application only authentication after you do base64 you need to remove new lines from authValue otherwise the header field won't be set.
Or just use already written Objective-C library for Twitter REST API 1.1 (https://github.com/nst/STTwitter).

Can't send data from objective-c via POST

i'm developing an app for iPhone and I'm stuck in one call, I have to send data via POST, the django web programmer tells me the app has to receive
param_one = request.POST['param_one']
param_two = request.POST['param_two']
but I cannot make it to send any data...
I'm learning objective-c, so please, could you tell me how to do it with an example?
PS: all the other calls that doesn't send any data, or pass data through url (GET method) works fine, so I'm making the connection correctly
Here's the code I'm using:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:#"somename" forKey:#"user"];
NSString *jsonString = [dict JSONRepresentation];
NSData *jsonData = [jsonString dataUsingEncoding:NSUTF8StringEncoding];
NSMutableURLRequest *  request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:#"http://web.com/custom/url/call/"]];
[request setValue:jsonString forHTTPHeaderField:#"json"];
[request setHTTPMethod:#"POST"];
[request addValue:csrf forHTTPHeaderField:#"X-CSRFToken"];
[request setHTTPBody:jsonData];
senddata = [[NSURLConnection alloc] initWithRequest:request delegate:self];
You should probably add:
[request setValue:#"application/json; charset=UTF-8" forHTTPHeaderField:#"Content-Type"];
Then the server will know that what you're sending is UTF-8 encoded JSON and it will be able to parse it appropriately. Otherwise it just gets a formless blob of data.
Unless it's for debugging purposes, it's very odd that you put the JSON string into both the header and the body.

Why does my NSURLMutableRequest POST request act like a GET request?

I've got a problem with my objective c code. I have a API-key protected WCF API that I built that takes POST requests and writes them to a Java servlet with C#. Anyway, this works great when testing with Fiddler, not so good from objective C. When I try to run the POST from my objective C, it "acts" like the NSURLMutableRequest is looking for a GET, in that the response only returns some default code I have written in for the GET method. Does anybody know why this is, and, moreover, what I can do to fix it? Here is the code that I use (quite successfully) to make other POST requests in with objective C.
is the problem the fact that I specify the API key in the URL for the NSMutableRequest? That's the only thing I can figure.
Here is the code:
NSString* theMessage = [NSString stringWithFormat:#"<MyRequestObject xmlns='http://schemas.datacontract.org/2004/07/MyService'></MyRequestObject>"];
NSMutableURLRequest *theRequest=[NSMutableURLRequest requestWithURL:[NSURL URLWithString:POST_API_URL]
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:240.0];
[theRequest setHTTPMethod:#"POST"];
[theRequest setValue:#"text/xml" forHTTPHeaderField:#"Content-Type"];
[theRequest setHTTPBody:[theMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSString *msgLength = [NSString stringWithFormat:#"%d", [theMessage length]];
[theRequest addValue: msgLength forHTTPHeaderField:#"Content-Length"];
NSURLResponse* response;
NSError *error;
NSData* result = [NSURLConnection sendSynchronousRequest:theRequest returningResponse:&response error:&error];
I ended up using ASIHTTPRequest to run the POST request to the WCF REST service, and now everything seems to be running smoothly. This means that there's probably some sort of URL Encoding mechanism for the API key that's going on behind the scenes that was poorly documented for NSMutableURLRequest, who knows. The good thing is, I've got the issue fixed. Here is the code I used:
ASIHTTPRequest *request = [ASIHTTPRequest requestWithURL:[NSURL URLWithString:POST_API_URL]];
[request appendPostData:[[NSString stringWithFormat:#"<MyRequest xmlns='http://schemas.datacontract.org/2004/07/MyService'>all of my request params in here</MyRequest>"] dataUsingEncoding:NSUTF8StringEncoding]];
[request setRequestMethod:#"POST"];
[request addRequestHeader:#"Content-Type" value:#"text/xml"];
[request startSynchronous];
Did you try setting the Content-Length header? WCF/IIS might be ignoring the body if it doesn't have its length defined in as a header.

NSMutableURLRequest: Can't get body to add with PUT request

I am trying to perform a PUT. As a test, I execute a GET request on some JSON data and store this receivedData in a variable data that I have initialized elsewhere. I am able to decode the original data and everything looks fine. When I send it back I wipe out everything in the HTTP body of the URI I am PUTting to.
data = receivedData:
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:putURI]] autorelease];
[request setTimeoutInterval:10];
[request setHTTPMethod:#"PUT"];
[request setValue:#"application/json" forHTTPHeaderField:#"Content-type"];
[request addValue:self.token forHTTPHeaderField:#"Authorization"];
[request setHTTPBody:data];
NSLog(#"\nVerify existence of original data packet: \n%#\n\n",data);
self.putDeviceOnListConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];
Any ideas what is wrong? Your help is greatly appreciated, as always.
I have found the problem with this. I have added a addValue:forHTTPHeaderField for for the length of the data packet and changed the content-type to "application/x-www-form-urlencoded.