要回答我自己的问题,答案是否定的。此外,Apple 提供的挑战发送器没有实现整个NSURLAuthenticationChallengeSender
协议,因此当客户端尝试响应挑战时会崩溃:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFURLSessionConnection performDefaultHandlingForAuthenticationChallenge:]: unrecognized selector sent to instance 0x7ff06d958410'
我的解决方案是创建一个包装器:
@interface CPURLSessionChallengeSender : NSObject <NSURLAuthenticationChallengeSender>
- (instancetype)initWithSessionCompletionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;
@end
@implementation CPURLSessionChallengeSender
{
void (^_sessionCompletionHandler)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential);
}
- (instancetype)initWithSessionCompletionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler
{
self = [super init];
if(self)
{
_sessionCompletionHandler = [completionHandler copy];
}
return self;
}
- (void)useCredential:(NSURLCredential *)credential forAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
_sessionCompletionHandler(NSURLSessionAuthChallengeUseCredential, credential);
}
- (void)continueWithoutCredentialForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
_sessionCompletionHandler(NSURLSessionAuthChallengeUseCredential, nil);
}
- (void)cancelAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;
{
_sessionCompletionHandler(NSURLSessionAuthChallengeCancelAuthenticationChallenge, nil);
}
- (void)performDefaultHandlingForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge
{
_sessionCompletionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
}
- (void)rejectProtectionSpaceAndContinueWithChallenge:(NSURLAuthenticationChallenge *)challenge
{
_sessionCompletionHandler(NSURLSessionAuthChallengeRejectProtectionSpace, nil);
}
@end
我用一个新的挑战对象替换了挑战对象,使用我包装的发件人:
NSURLAuthenticationChallenge* challengeWrapper = [[NSURLAuthenticationChallenge alloc] initWithAuthenticationChallenge:challenge sender:[[CPURLSessionChallengeSender alloc] initWithSessionCompletionHandler:completionHandler]];
[self.client URLProtocol:self didReceiveAuthenticationChallenge:challengeWrapper];