在 iPad 应用程序中,我需要连接到服务器并在后台模式下下载使用带有 NSURLSession
对象的自签名 SSL 证书的文件:
static NSString *const URL = @"https://...";
- (void)testBackgroundDownloadTask {
if (self.downloadTask) {
return self;
}
self.session = [self backgroundSession];
NSURL *downloadURL = [NSURL URLWithString:URL];
NSURLRequest *request = [NSURLRequest requestWithURL:downloadURL];
self.downloadTask = [self.session downloadTaskWithRequest:request];
[self.downloadTask resume];
}
- (NSURLSession *)backgroundSession{
static NSURLSession *sess = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:URL];
// Default configuration: working perfectly
//NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
configuration.sessionSendsLaunchEvents = YES;
//configuration.TLSMinimumSupportedProtocol = kSSLProtocolAll;
configuration.networkServiceType = NSURLNetworkServiceTypeBackground;
sess = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
});
return sess;
}
- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
NSURLProtectionSpace *protectionSpace = challenge.protectionSpace;
NSString *authMethod = protectionSpace.authenticationMethod;
if ([authMethod isEqualToString:NSURLAuthenticationMethodClientCertificate]) {
// obtain challenge, it working with NSURLSession in default session config
[self.challengeHandler handleChallenge:challenge onCompletion:^(id obj) {
NSURLCredential *c = (NSURLCredential *)obj;
if (c) {
[challenge.sender useCredential:c forAuthenticationChallenge:challenge];
completionHandler(NSURLSessionAuthChallengeUseCredential, c);
}
else {
[challenge.sender cancelAuthenticationChallenge:challenge];
}
}];
}
else if ([authMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]);
}
}
如果我使用defaultSessionConfiguration
,我的应用在调用didReceiveChallenge
方法后成功执行下载文件(调用NSURLSesionDownloadDelegate
方法
– URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:
– URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite:
– URLSession:downloadTask:didFinishDownloadingToURL:
但我使用backgroundSessionConfiguration
,在调用didReceiveChallenge
之后没有调用其他委托(delegate)的方法(文件没有下载和didCompleteWithError
没有调用)
关于如何解决此问题的任何想法?
最佳答案
你在后台测试这个吗?
在你的
NSURLSessionDownloadDelegate
上,你应该看到你在实现时得到了什么- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { NSLog(@"%s %@ %@", __PRETTY_FUNCTION__, task.response, error); }
如果
–URLSession:didReceiveChallenge:completionHandler:
中的任何内容是异步的,那么您需要用UIApplication
/UIBackgroundTaskIdentifier 包围它
{begin
,end
}BackgroundTask...
,否则 iOS 将在堆栈弹出时终止您的后台进程。
关于ios - NSURLSession 鉴权和后台下载文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21545572/