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 ;)