1
votes

I am making heavy use of Grand Central Dispatch. I now have the need to make a URL request of a server that requires authentication. The iOS approach NSURLConnection is asynchronous which complicates my use of GCD for async tasks. As I understand it NSURLConnection does support synchronous mode but this requires embedding user/pass in the requesting URL which makes no sense since I will not know that. What are my options here?

Thanks,
Doug

2
Is this a user-initiated action? If so, regardless of sync/async, why not just parse the response, and if it's an authentication challenge, present a username/password form to the user? I think you need to provide more context.Christopher Pickslay

2 Answers

0
votes

Unfortunately, your only option is to use the asynchronous requests. There is no way to handle authentication challenges with the sendSynchronousRequest:returningResponse:error: method.

0
votes

Actually, synchronous requests will check the keychain for an existing credential before failing. It will use the default credential if one exists. So, for example, somewhere in your code before you fire off your network connection:

NSURLProtectionSpace    *protectionSpace    = nil;
NSURLCredential         *credential         = nil;

// Note that you can't wildcard realm, if your server will present a realm you need that here as well.
protectionSpace = [[NSURLProtectionSpace alloc] initWithHost:@"foo.com" port:80 protocol:@"http" realm:nil authenticationMethod:NSURLAuthenticationMethodHTTPBasic];

// This creates the credential
credential = [NSURLCredential credentialWithUser:user password:pass persistence:NSURLCredentialPersistencePermanent];

// This stores it, in the application keychain.
[[NSURLCredentialStorage sharedCredentialStorage] setDefaultCredential:credential forProtectionSpace:protectionSpace];

Now it's set as the default credential for that protection space, and the URL loading system will look for and use that credential when accessing that protection space. Easy! The one thing this will NOT do is SSL based authentication - NSURLAuthenticationMethodClientCertificate and NSURLAuthenticationMethodServerTrust. For various reasons, NSURLConnection requires you to implement a delegate to evaluate the trust of the server and client in that case. For your basic auth problem though, with the above code you are set.

But to answer your larger question about GCD and NSURLConnection, you have options. Sure, you could do what all the blog posts say and use synchronous requests inside async blocks, and that may work for you (or explode). You can also use the newer method sendAsynchronousRequest:queue:completionHandler: . That will solve a lot of problems for you, as the delegate callbacks will run on the provided queue. It does make things much simpler!

This may also be worth reading: Five Reasons Synchronous Networking is Bad eskimo1 is something worth listening to ;)