POST request in Objective-C - objective-c

Searching the web for some method to send POST requests in Objective-C, I came up with some solutions.
That's what I've got:
responseData = [NSMutableData new];
NSURL *url = [NSURL URLWithString:#"http://mydomain.com/page.php?"];
NSString *myParameters = [[NSString alloc] initWithFormat:#"str=hello"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"POST"];
[request setHTTPBody:[myParameters dataUsingEncoding:NSUTF8StringEncoding]];
The response I receive is an error, because the POST variable "str" hasn't been set.
What am I doing wrong?

You will have to:
set the content type header of the request ("application/x-www-form-urlencoded"). You can set the header by using the setValue:forHTTPHeaderField: method of an NSMutableURLRequest instance.
make sure, that the body actually is actually "Form URL encoded". The example you give looks good, but if you add other parameters, or parameter values containing special characters, make sure, that these are properly encoded. See CFURLCreateStringByAddingPercentEscapes.

It looks like your parameters are intended to be URL parameters (typically in name1=value1&name2=value2 form). You usually don't want to put them in the HTTP body like you are currently doing. Instead, append them to your URL:
NSString *requestStr = #"hello";
NSString urlString = [NSString stringWithFormat:#"http://mydomain.com/page.php?str=%#", requestStr];
NSURL *url = [NSURL URLWithString:urlString];
NSURLRequest doesn't provide a more generic way to do this, although you can look at this SO question and its answers for ideas on how many people deal with this kind of requirement. There are also free and/or open source libraries out there that aim to make this kind of request easier to code.

Related

NSURLConnection Unable to http post large file

We are trying to add in functionality into our app to allow it to POST a large file approx 50kb to our web service the file itself is a HTML template, however with the code below what we are finding is that the data seems to get cut off when the web service saves it.
The web service is currently designed to check the $_POST['html'] variable and write it to a file.
Is there a better way to do this and does anyone have any idea why the upload is not complete?
Thanks Aaron
NSString *myText;
NSString *filePath = [[NSBundle mainBundle] pathForResource:#"template" ofType:#"htm"];
if (filePath) {
myText = [NSString stringWithContentsOfFile:filePath encoding:NSUTF8StringEncoding error:nil];
}
NSURL *URL = [NSURL URLWithString:#"http://mywebsiteurl.com/receiveData.php"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
request.HTTPMethod = #"POST";
NSString *params = [NSString stringWithFormat:#"html=%#", myText];
NSData *data = [params dataUsingEncoding:NSASCIIStringEncoding];
[request addValue:#"8bit" forHTTPHeaderField:#"Content-Transfer-Encoding"];
[request addValue:#"application/x-www-form-urlencoded" forHTTPHeaderField:#"Content-Type"];
[request addValue:[NSString stringWithFormat:#"%i", [data length]] forHTTPHeaderField:#"Content-Length"];
[NSURLConnection connectionWithRequest:[request autorelease] delegate:self];
I think it is because your Server set the post limit.Check the settings at your server side about the post data limit.
When I rechecked this question, I think maybe I found what was the problem. When I do HTTP post, I usually don't set the content-length by myself. I just encode my post data as key=value&.. form and use the [NSMutableURLRequest setHTTPBody:data] method to add the data to the NSMutableURLRequest. I think it will do the rest for you include set the content-length for you. Even though I am not very familiar with HTTP protocol, but I think maybe the content-length represent the whole post data length, but here you set the content-length value with the length of key value data length.

How to encode sharp sign in NSURL

I have this scenario that I need to send a GET http request to the remote server. I went with NSURLConnection and intercept the request in HTTPScoop.
The url format is something like this:
http://domain.com?key=username##somehash&url=someotherurl.com
I am doing it like this:
NSString *urlString = [[NSString alloc]init];
urlString = #"http://domain.com?key=username##somehash&url=someotherurl.com";
NSString *encodedString = [urlString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSURL *url = [NSURL URLWithString: [NSString stringWithFormat:encodedString]];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
[request setHTTPMethod:#"GET"];
NSURLConnection *theConnection=[[NSURLConnection alloc] initWithRequest:request delegate:self];
In this case I didn't escape the # sign, and the request I see in httpscoop is:
http://domain.com?key=username223somehash&url=someotherurl.com
If I escape the sharp sign to %23, it gets to something like this in httpscoop:
http://domain.com?key=username22523somehash&url=someotherurl.com
I have tried different combinations but always have issue with the sharp sign. Are there any walk-around for this? Thanks!
replace # with %23 (source).
edit - oops, didn't see the rest of your message. Not sure about NSURL, but I have had difficulty encoding parameters in URLs with NSURL before, too. I ended up using ASIHTTPRequest, which took care of all the encoding issues. I would recommend doing the same.

Getting webpage from data object

I'm fairly new to objective c but I'm using this code
NSURL *url = [NSURL URLWithString:#"http://xxx.com"];
NSURLRequest *req = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReturnCacheDataElseLoad timeoutInterval:30];
NSURLResponse *resp = nil;
NSData *data = [NSURLConnection sendSynchronousRequest:req returningResponse:&resp error:nil];
NSLog(#"received %???", [data XYZ]);
to try and grab the raw content of a webpage. What would I have to insert instead of XYZ (and obviously ???) so that I could just print the website data. I know that the code pulls some data down because I can use XYZ = length to get the size of the incoming data. If anyone could help, that would be great!
(If anyone could additionally explain how I could have found this in the apple documentation, that would also be really useful)
I assume you mean converting the NSData to a NSString so you can print it?
You should use
[NSString stringWithData:data encoding:NSUTF8StringEncoding]
to create a string from the data. Note that the encoding is not UTF8 for all websites so it might not produce the correct output always.
You can easily find these methods by browsing the online documentation: http://developer.apple.com/library/ios/#documentation/Cocoa/Reference/Foundation/Classes/NSString_Class/Reference/NSString.html

NSMutableURLRequest with multiple headers

I'm trying to create a synchronous REST request to an API. The API uses HTTP Basic authentication, so in addition to sending an Accept: application/json header, I need to specify the Authorization header as well with my Base64-encoded username and password pair. When I use just one header the request executes just fine (either successfully authenticating me, or specifying my content format), but when I use both headers, it seems to ignore the Authorization line and returns "HTTP Basic access denied" (presumably a 401).
So I can't for the life of me figure out whats wrong. I'm 100% sure my credentials are valid, because executing the request via REST client works just fine. I'm pretty new to Objective-C so I think perhaps there could be some kind of design pattern I'm not following. Is it valid to call setValue:forKey on an NSMutableDictionary multiple times like that? I also tried using setValue:forHTTPHeader on the request object with the same results.
Here's the code:
NSURL *url = [NSURL URLWithString:#"http://foo.com/api/v1/bar"];
NSMutableURLRequest *request= [NSMutableURLRequest requestWithURL:url];
NSMutableDictionary *headers = [NSMutableDictionary dictionary];
NSURLResponse *urlResponse;
NSError *error;
[headers setValue:#"application/json" forKey:#"Accept"];
[headers setValue:#"Basic ..." forKey:#"Authorization"];
[request setAllHTTPHeaderFields:headers];
NSData *urlData = [NSURLConnection sendSynchronousRequest:request
returningResponse:&urlResponse
error:&error];
NSString *responseString = [[NSString alloc] initWithData:urlData
encoding:NSUTF8StringEncoding];
NSLog(#"%#",responseString);
The answer is to use:
[request addValue:#"Basic ..." forHTTPHeaderField:#"Authorization"];
Which adds another header into the request instance.

NSURLRequest returning null

Someone knows why I'm getting null in this code?
NSURLRequest *requisicao = [NSURLRequest requestWithURL:
[NSURL URLWithString:URLAddress]];
When I debug this line and preview the content of this variable, I receive null -
"<NSURLRequest (null)>"
My URLAddress is a request for a JSON service.
It's most likely null because URLAddress contains characters that need to be percent-escaped (which is what the URLWithString method needs).
Try using stringByAddingPercentEscapesUsingEncoding:
NSURLRequest *requisicao = [NSURLRequest requestWithURL:
[NSURL URLWithString:
[URLAddress stringByAddingPercentEscapesUsingEncoding:
NSUTF8StringEncoding]]];
However, see this answer by Dave DeLong which points out limitations of stringByAddingPercentEscapesUsingEncoding and alternatives to it.