我正在大量使用 Grand Central Dispatch。我现在需要向需要身份验证的服务器发出 URL 请求。iOS 方法NSURLConnection
是异步的,这使我将 GCD 用于异步任务变得复杂。据我了解,它NSURLConnection
确实支持同步模式,但这需要在请求 URL 中嵌入用户/密码,这是没有意义的,因为我不知道。我在这里有什么选择?
谢谢,
道格
我正在大量使用 Grand Central Dispatch。我现在需要向需要身份验证的服务器发出 URL 请求。iOS 方法NSURLConnection
是异步的,这使我将 GCD 用于异步任务变得复杂。据我了解,它NSURLConnection
确实支持同步模式,但这需要在请求 URL 中嵌入用户/密码,这是没有意义的,因为我不知道。我在这里有什么选择?
谢谢,
道格
不幸的是,您唯一的选择是使用异步请求。该方法无法处理身份验证挑战sendSynchronousRequest:returningResponse:error:
。
实际上,同步请求会在失败之前检查钥匙串是否存在现有凭证。如果存在,它将使用默认凭据。因此,例如,在您启动网络连接之前,在您的代码中的某个位置:
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];
现在它被设置为该保护空间的默认凭据,并且 URL 加载系统将在访问该保护空间时查找并使用该凭据。简单的!这不会做的一件事是基于 SSL 的身份验证 - NSURLAuthenticationMethodClientCertificate 和 NSURLAuthenticationMethodServerTrust。由于各种原因,NSURLConnection 要求您实现一个委托来评估这种情况下服务器和客户端的信任。但是,对于您的基本身份验证问题,您可以使用上面的代码进行设置。
但是要回答有关 GCD 和 NSURLConnection 的更大问题,您可以选择。当然,你可以按照所有博客文章所说的去做,并在异步块中使用同步请求,这可能对你有用(或爆炸)。您也可以使用较新的方法sendAsynchronousRequest:queue:completionHandler:
。这将为您解决很多问题,因为委托回调将在提供的队列上运行。它确实让事情变得简单多了!
这可能也值得一读:同步网络不好 的五个原因爱斯基摩人值得一听;)