Authentication and loading NSURLSession in the background

In the iPad application, I need to connect to the server and upload files using a self-signed SSL certificate with the object NSURLSessionin the background:

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]);
    }
}

If I use defaultSessionConfiguration, my application after the call didReceiveChallengesuccessfully downloads the file (call the NSURLSesionDownloadDelegatemethods

– URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes
– URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesExpectedToWrite
– URLSession:downloadTask:didFinishDownloadingToURL

But I use backgroundSessionConfiguration, after calling didReceiveChallengeother methods of delegates that are not called (the file does not load and is didCompleteWithErrornot called) Any ideas on how to solve this problem?

+4
source share
1 answer
  • Are you testing this in the background?

  • 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 , .

0

Source: https://habr.com/ru/post/1525164/


All Articles