Reputation: 3
I have a basic question and I am hoping there is a simple answer that I have missed. The basic premise is that I am going to connect to a website and download some JSON data. I am using the framework provided by Stig Brautaset and the tutorial worked really well.
My issue is that the website I am connecting to is in the format and the username and password are fixed for my app so the user will never be entering them.
curl -u username:password http://website.com/page
How do I pass in the url and password to a NSURLConnection
?
It doesn't have to be an NSURLConnection
, it just seems the best option.
I have looked at the AdvancedUrlConnections
sample but it seems overly complex and is quite old. Searching on the web hasn't been much better. I am hoping that one of you guys can say just set these 2 properties, followed by suitable insults of course...
Upvotes: 0
Views: 1015
Reputation: 18477
An NSURLConnection will work just fine. As pointed out in another answer, implementing the didReceiveAuthenticationChallenge
callback is quite easy to do.
- (void) someMethod
{
NSURLRequest* request = [[NSURLRequest alloc]
initWithURL:[NSURL urlWithString:@"someURL"]
NSURLConnection* connection = [[NSURLConnection alloc]
initWithRequest:request delegate:self];
[connection release];
[request release];
}
This is all pretty straight forward. It's in the delegate methods of the NSURLConnection where all the magic happens:
This is where you handle the challenge for credentials. I have hardcoded a fake username and password to demonstrate how it works. I personally have a separate delegate object handle the challenge. Keep in mind that the connection will sit in an idle state until you respond to it or until the connection times out.
- (void) connection:(NSURLConnection *)connection
didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
// Make sure to use the appropriate authentication method for the server to
// which you are connecting.
if ([[challenge protectionSpace] authenticationMethod] ==
NSURLAuthenticationMethodBasicAuth)
{
// This is very, very important to check. Depending on how your
// security policies are setup, you could lock your user out of his
// or her account by trying to use the wrong credentials too many
// times in a row.
if ([challenge previousFailureCount] > 0)
{
[[challenge sender] cancelAuthenticationChallenge:challenge];
UIAlertView* alert = [[UIAlertView alloc]
initWithTitle:@"Invalid Credentials"
message:@"The credentials are invalid."
delegate:nil
cancelButtonTitle:@"OK"
otherButtonTitles:nil];
[alert show];
[alert release];
}
else
{
[challenge useCredential:[NSURLCredential
credentialWithUser:@"someUser"
password:@"somePassword"
persistence:NSURLCredentialPersistenceForSession
forAuthenticationChallenge:challenge]];
}
}
else
{
// Do whatever you want here, for educational purposes,
// I'm just going to cancel the challenge
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
You'll need to implement these other methods for an NSURLConnection, as well:
// So you know when it's done downloading
- (void) connectionDidFinishLoading:(NSURLConnection *)connection;
// In case of failure
- (void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error;
// Gather the downloaded file data
- (void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data;
Upvotes: 3
Reputation: 70946
There are a couple of possibilities.
If you use an asynchronous NSURLConnection, the method -connection:didReceiveAuthenticationChallenge:
will be called on the connection's delegate. The docs for this method explain how to deal with it. It's what AdvancedUrlConnections
uses and yeah, it's a little messy.
A simpler approach is to create an NSMutableURLRequest
when creating the connection (instead of an immutable NSURLRequest
). That allows you to add arbitrary HTTP headers. Constructing a basic auth header is simple-- something like
NSMutableURLRequest *request = .... // details omitted
NSString *username = // ....
NSString *password = // ....
NSData *authRawData = [[NSString stringWithFormat:@"%@:%@", username, password] dataUsingEncoding:NSUTF8StringEncoding];
NSString *authEncoded = [authRawData asBase64EncodedString];
[request setValue:[NSString stringWithFormat:@"Basic %@", authEncoded] forHTTPHeaderField:@"Authorization"];
The above uses the -asBase64EncodedString
method included in TouchFoundation
Upvotes: 0