iOS: how to perform a HTTP POST request?
I'm approaching iOS development and I'd like to have one of my first applications to perform a HTTP POST request.
As far as I can understand, I should manage the connection which handles the request via a NSURLConnection
object, which forces me to have a delegate object, which in turn will handle data events.
Could someone please clarify the task with a practical example?
I should contact an https endpoint sending authentication data (username and password) and getting back a plain text response.
Solution 1:
You can use NSURLConnection as follows:
-
Set your
NSURLRequest
: UserequestWithURL:(NSURL *)theURL
to initialise the request.If you need to specify a POST request and/or HTTP headers, use
NSMutableURLRequest
with(void)setHTTPMethod:(NSString *)method
(void)setHTTPBody:(NSData *)data
(void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field
-
Send your request in 2 ways using
NSURLConnection
:-
Synchronously:
(NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error
This returns a
NSData
variable that you can process.IMPORTANT: Remember to kick off the synchronous request in a separate thread to avoid blocking the UI.
Asynchronously:
(void)start
-
Don't forget to set your NSURLConnection's delegate to handle the connection as follows:
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
[self.data setLength:0];
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)d {
[self.data appendData:d];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[[[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Error", @"")
message:[error localizedDescription]
delegate:nil
cancelButtonTitle:NSLocalizedString(@"OK", @"")
otherButtonTitles:nil] autorelease] show];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
NSString *responseText = [[NSString alloc] initWithData:self.data encoding:NSUTF8StringEncoding];
// Do anything you want with it
[responseText release];
}
// Handle basic authentication challenge if needed
- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge {
NSString *username = @"username";
NSString *password = @"password";
NSURLCredential *credential = [NSURLCredential credentialWithUser:username
password:password
persistence:NSURLCredentialPersistenceForSession];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
Solution 2:
EDIT: ASIHTTPRequest has been abandoned by the developer. It's still really good IMO, but you should probably look elsewhere now.
I'd highly recommend using the ASIHTTPRequest library if you are handling HTTPS. Even without https it provides a really nice wrapper for stuff like this and whilst it's not hard to do yourself over plain http, I just think the library is nice and a great way to get started.
The HTTPS complications are far from trivial in various scenarios, and if you want to be robust in handling all the variations, you'll find the ASI library a real help.