gpt4 book ai didi

ios - NSURLSessionTask 身份验证挑战完成处理程序和 NSURLAuthenticationChallenge 客户端

转载 作者:可可西里 更新时间:2023-11-01 05:28:34 24 4
gpt4 key购买 nike

我正在实现自定义 NSURLProtocol,并且在内部希望使用 NSURLSession 处理内部网络的数据任务,而不是 NSURLConnection

我遇到了一个有趣的问题,想知道 NSURLSession/NSURLSessionTask 的挑战处理程序的内部实现。

- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task
didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge
completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler;

这里基本上提供了两个不同的挑战处理程序,一个是 completionHandler block ,它提供了处理挑战的所有必要信息,但还有遗留的 NSURLAuthenticationChallenge。 client 具有与 completionHandler 信息选项几乎一一对应的方法。

由于我正在开发一个协议(protocol),并且想将某些身份验证挑战向上传递给 URL 加载系统以供调用 API 实现,我需要使用 NSURLSession 客户端方法:

- (void)URLProtocol:(NSURLProtocol *)protocol didReceiveAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge;

我的问题是 completionHandlerNSURLAuthenticationChallenge.client 的内部实现是否相同,如果是,我可以跳过在委托(delegate)方法中调用完成处理程序吗,期望 URL 加载系统将调用适当的 NSURLAuthenticationChallenge.client 方法?

最佳答案

回答我自己的问题,答案是否定的。此外,Apple 提供的质询发送器并未实现整个 NSURLAuthenticationChallengeSender 协议(protocol),因此当客户端尝试响应质询时会崩溃:

*** 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];

关于ios - NSURLSessionTask 身份验证挑战完成处理程序和 NSURLAuthenticationChallenge 客户端,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27604052/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com