用ssl同步子类化NSURLConnection?

时间:2014-04-07 15:20:07

标签: ios objective-c ssl nsurlconnection synchronous

我将NSURLConnection子类化为使用ssl调用Web服务。 我认为这样做是同步的,而不仅仅是现在的异步连接。

我的代码:

#import "SecureSSLConnection.h"

static NSMutableArray *sharedConnectionList = nil;

@implementation SecureSSLConnection
@synthesize request, completionBlock, internalConnection;

- (id)initWithRequest:(NSMutableURLRequest *)req
{
    self = [super init];
    if (self) {
        self.request = req;
    }
    return self;
}

- (void)start
{
    container = [NSMutableData new];
    internalConnection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:YES];

    if (!sharedConnectionList) {
        sharedConnectionList = [NSMutableArray new];
    }
    [sharedConnectionList addObject:self];    
}

#pragma mark - NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    [container appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    if (self.completionBlock) {
        self.completionBlock(container, nil);
    }

    [sharedConnectionList removeObject:self];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
    if (self.completionBlock) {
        self.completionBlock(nil, error);
    }

    [sharedConnectionList removeObject:self];
}

#pragma mark - SSL Connection Addition

- (BOOL)connection:(NSURLConnection *)connection canAuthenticateAgainstProtectionSpace:(NSURLProtectionSpace *)protectionSpace
{
    return [protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust];
}

- (void)connection:(NSURLConnection *)connection didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
    NSLog(@"challenge.protectionSpace.host: %@", challenge.protectionSpace.host);

    if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        // We only trust our own domain
        if ([challenge.protectionSpace.host isEqualToString:WebSiteURL]) {
            NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
            [challenge.sender useCredential:credential forAuthenticationChallenge:challenge];
        }
    }

    [challenge.sender continueWithoutCredentialForAuthenticationChallenge:challenge];
}

我开始考虑实施:

+ (NSData *)sendSynchronousRequest:(NSURLRequest *)request returningResponse:(NSURLResponse **)response error:(NSError **)error

为了使其与原始代表保持一致。

一种方法是使用NSNotificationCenter,但我的目标是更简单的方法。

任何想法我该怎么做?

1 个答案:

答案 0 :(得分:2)

我不建议将此同步。您总是希望保持网络请求的异步。

简单的解决方案是使用您的完成块属性。只需将依赖于初始SSL请求的其他任务放在第一个请求的完成块中。这样,他们就不会开始直到第一次完成。

更优雅的解决方案是更进一步,并将SSL请求包装在并发的NSOperation子类中。这样,您不仅可以使用上述完成块模式,还可以使用后续操作的addDependencymaxConcurrentOperationCount的{​​{1}}来真正优化各种操作之间的动态。这是非常重要的,但您可以看到AFNetworking的一个相对深思熟虑的实现此模式的示例。