我已经在我的类中实现了NSURLConnectionDataDelegate,并且我实现了该方法:
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
但是当我制作新的NSURLConnection时,这个方法并没有被调用。为什么?问题出在哪儿?连接是SSL连接。
我查看了一个通过互联网下载的示例项目(我不记得在哪里),这个项目工作得很好,但是如果我在项目中做了一些步骤,那就不行了。我需要任何外部库或在项目中设置一些东西?你可以建议我一个for-dummies指南吗?
编辑1: 在我使用的示例中:
NSURL *httpsURL = [NSURL URLWithString:@"https://secure.skabber.com/json/"];
NSURLRequest *request2 = [NSURLRequest requestWithURL:httpsURL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:15.0f];
NSURLConnection *connection = [NSURLConnection connectionWithRequest:request2 delegate:self];
[connection start];
但我想使用任何类型的NSURLConnection。
编辑2:
这是我的完整代码:
@interface ConnectionDelegate : NSObject<NSURLConnectionDataDelegate>
@property (strong, nonatomic) NSURLConnection *connection;
@property (strong, nonatomic) NSMutableData *responseData;
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
-(void)testHTTPRequest;
@end
@implementation ConnectionDelegate
-(void)testHTTPRequest
{
NSURL *httpsURL = [NSURL URLWithString:@"https://secure.skabber.com/json/"];
NSURLRequest *request = [NSURLRequest requestWithURL:httpsURL cachePolicy:NSURLRequestReloadIgnoringLocalAndRemoteCacheData timeoutInterval:15.0f];
self.connection = [NSURLConnection connectionWithRequest:request delegate:self];
[self.connection start];
if ([self isSSLPinning]) {
[self printMessage:@"Making pinned request"];
}
else {
[self printMessage:@"Making non-pinned request"];
}
}
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
SecTrustRef serverTrust = challenge.protectionSpace.serverTrust;
SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, 0);
NSData *remoteCertificateData = CFBridgingRelease(SecCertificateCopyData(certificate));
NSData *skabberCertData = [self skabberCert];
if ([remoteCertificateData isEqualToData:skabberCertData] || [self isSSLPinning] == NO) {
if ([self isSSLPinning] || [remoteCertificateData isEqualToData:skabberCertData]) {
[self printMessage:@"The server's certificate is the valid secure.skabber.com certificate. Allowing the request."];
}
else {
[self printMessage:@"The server's certificate does not match secure.skabber.com. Continuing anyway."];
}
NSURLCredential *credential = [NSURLCredential credentialForTrust:serverTrust];
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
}
else {
[self printMessage:@"The server's certificate does not match secure.skabber.com. Canceling the request."];
[[challenge sender] cancelAuthenticationChallenge:challenge];
}
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
if (self.responseData == nil) {
self.responseData = [NSMutableData dataWithData:data];
}
else {
[self.responseData appendData:data];
}
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSString *response = [[NSString alloc] initWithData:self.responseData encoding:NSUTF8StringEncoding];
[self printMessage:response];
self.responseData = nil;
}
- (NSData *)skabberCert
{
NSString *cerPath = [[NSBundle mainBundle] pathForResource:@"secure.skabber.com" ofType:@"cer"];
return [NSData dataWithContentsOfFile:cerPath];
}
- (void)printMessage:(NSString *)message
{
Log(@"%@",message);
}
- (BOOL)isSSLPinning
{
NSString *envValue = [[[NSProcessInfo processInfo] environment] objectForKey:@"SSL_PINNING"];
return [envValue boolValue];
}
@end
如果我在连接上设置断点:willSendRequestForAuthenticationChallenge:程序不会输入。