From another thread, here’s a authentication handler for a delegate of a NSURLSessionDownloadTask: - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition, NSURLCredential *))completionHandler { if (self.usernameAndPassword && ([challenge.protectionSpace.authenticationMethod isEqual:NSURLAuthenticationMethodDefault] || [challenge.protectionSpace.authenticationMethod isEqual:NSURLAuthenticationMethodHTTPBasic] || [challenge.protectionSpace.authenticationMethod isEqual:NSURLAuthenticationMethodHTTPDigest] || [challenge.protectionSpace.authenticationMethod isEqual:NSURLAuthenticationMethodNTLM])) { // Password-based authentication completionHandler([challenge.proposedCredential isEqual:self.usernameAndPassword] ? NSURLSessionAuthChallengeRejectProtectionSpace : NSURLSessionAuthChallengeUseCredential, self.usernameAndPassword); } else { completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } }
I thought of replacing all those individual tests on challenge.protectionSpace.authenticationMethod to a NSSet membership test. Then I thought it should be a function global, so I made the NSSet pointer static and added a dispatch_once block (code dragged from the Xcode sample set) to initialize it. Everything seemed to be fine. Then I switched from testing my two URLs with authentication one at a time to both at once. One hasn’t been working ever, but the one that has always worked now doesn’t. The newly broken one either gets a NSURLDomainError -1013 or it goes all the way through, but delivers a zero-byte file as if authentication failed instead of the non-empty JSON file it delivers upon true success.
I replaced the function-static NSSet with an on-the-fly object created at the last minute in the “if” test block. That didn’t seem to work either. I went back to the individual tests and that worked. But I went back to the NSSet versions and they started working! Then they didn’t; I had the worst kind of error, where the code should work, but threading issues are causing some sort of time-out.
Then I remembered that I set the NSURLSession to use the main thread (set its queue to [NSOperationQueue mainQueue]). Could that serialization cause a challenge to sometimes time out? If you leave the session queue as NIL, is the queue automatically created instead one that allows multiple operations at once? If so, and I use it, do I have to switch all my properties (which include NSArray, NSDictionary, and NSInteger) from the usual “nonatomic” to atomic?
— Daryle Walker Mac, Internet, and Video Game Junkie darylew AT mac DOT com
|