Swift 2 nil NSURLSessionDataTask при добавлении конфигурации

Когда sessionустановлен как .init(configuration:..., delegate:self, delegateQueue:NSOperationQueue.mainQueue())для прокси сервера редирект, NSURLSessionDataTask.resume()не приводит к выполнению task. Когда sessionустановлено как.sharedSession(), taskвыполняется как ожидалось.

**kCFStreamPropertyHTTPProxyHost etc. были осуждены. Может это влияет NSURLSessionConfigurationтаким образом, что мешает выполнению task?

class ConnectionManager: NSURLSession, NSURLSessionDelegate {
    .
    .
    .
    if shouldUseProxy {
            let proxyEnable = NSNumber(int: 1) as CFNumber
            let  proxyDict: [NSObject:AnyObject] = [
                kCFNetworkProxiesHTTPEnable: proxyEnable,
                kCFStreamPropertyHTTPProxyHost: proxyHost,
                kCFStreamPropertyHTTPProxyPort: proxyPort,
                kCFStreamPropertyHTTPSProxyHost: proxyHost,
                kCFStreamPropertyHTTPSProxyPort: proxyPort,
                kCFProxyTypeKey: kCFProxyTypeHTTPS,
                kCFProxyUsernameKey: proxyUser,
                kCFProxyPasswordKey: proxyPW
            ]

            let config = NSURLSessionConfiguration.ephemeralSessionConfiguration()
            config.connectionProxyDictionary = proxyDict
            self.session = NSURLSession.init(configuration: config, delegate: self, delegateQueue: NSOperationQueue.mainQueue())
    } else {
        self.session = NSURLSession.sharedSession()
    }

        self.task = self.session.dataTaskWithRequest(request) {
            (data, response, error) in
            if error == nil {
                self.cookies = NSHTTPCookieStorage.sharedHTTPCookieStorage().cookiesForURL(response!.URL!)!

                self.httpResponse = (response as? NSHTTPURLResponse)!
                self.statusCode = (self.httpResponse!.statusCode)
                guard error == nil && data != nil else {
                    print(error)
                    return
                }

                do {
                    if self.statusCode == 200 {
                        self.contentsOfURL = try NSString(contentsOfURL: self.URL, encoding: NSUTF8StringEncoding) as String
                    }
                } catch {

                }
            }
        }

        self.task?.resume()
        .
        .
        .
}

1 ответ

  1. Настройка конфигурации

    В большинстве случаев конфигурация по умолчанию работает, если вам не нужно что-то особенное.

    let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration()
    
    let session = NSURLSession(configuration: sessionConfiguration,
                               delegate: self,
                               delegateQueue: operationQueue)
    

    Пожалуйста, обратитесь к документации Apple: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/doc/uid/TP40013435-CH1-SW7

    Ответ перенаправления

    NSURLSessionDelegate имеет ниже упомянутую функцию, которая вызывается, когда происходит перенаправление.

    func URLSession(session: NSURLSession, task: NSURLSessionTask, willPerformHTTPRedirection response: NSHTTPURLResponse, newRequest request: NSURLRequest, completionHandler: (NSURLRequest?) -> Void) {
    
        //self.completionHandler is some completion handler you have defined, it is call back function.
    
        if cancelled {
            self.completionHandler(nil, redirectRequest:nil, wasCancelled: true)
        }
        else {
            self.completionHandler(nil, redirectRequest:request, wasCancelled: false)
        }
    
        finished = true
        executing = false
    }
    

    Существует параметрrequest, который содержит новый URLRequest. Теперь вы должны инициировать новую задачу сеанса с этим новым запросом

    Вызов

    Эта функция является частью NSURLSessionDelegate

    При получении вызова вызывается следующая функция. В зависимости от типа задачи, вы должны справиться с ней соответствующим образом.

    См. комментируемый код для NSURLAuthenticationMethodHTTPBasicand NSURLAuthenticationMethodHTTPDigest

    func URLSession(session: NSURLSession,
        didReceiveChallenge challenge: NSURLAuthenticationChallenge,
        completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) {
    
            print("Challenge:")
    
            if(challenge.previousFailureCount == 0) {
    
                let credential = credentialForChallenge(challenge)
                print("Use Credential ....\n")
                completionHandler(.UseCredential, credential)
            }
            else {
                print("Previous Failure Count = \(challenge.previousFailureCount)")
                print("Cancelling Challenge\n")
                challenge.sender?.cancelAuthenticationChallenge(challenge)
            }
    }
    
    //Custom method to get the credential for the challenge
    //In your case you would be interested in NSURLAuthenticationMethodHTTPBasic
    func credentialForChallenge(challenge : NSURLAuthenticationChallenge) -> NSURLCredential? {
    
        //https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/URLLoadingSystem/Articles/AuthenticationChallenges.html
        //challenge knows:
        //what triggered the challenge
        //how many attempts were made for the challenge - previousFailureCount
        //any previous attempted credentials - proposedCredential
        //the NSURLProtectionSpace that requires the credentials
        //sender of the challenge
    
        //#Respond
        //Get authentication method
    
        let credential : NSURLCredential?
    
        print("Method = \(challenge.protectionSpace.authenticationMethod)")
    
        switch(challenge.protectionSpace.authenticationMethod) {
    
        case NSURLAuthenticationMethodHTTPBasic:
            //            HTTP basic authentication
            //            prompt user for username and password
            //            let credential = NSURLCredential(user: <#T##String#>, password: <#T##String#>, persistence: <#T##NSURLCredentialPersistence#>)
            credential = nil
    
    
        case NSURLAuthenticationMethodHTTPDigest:
            //            HTTP digest authentication
            //            prompt user for username and password
            //            let credential = NSURLCredential(user: <#T##String#>, password: <#T##String#>, persistence: <#T##NSURLCredentialPersistence#>)
    
            credential = nil
    
    
        case NSURLAuthenticationMethodClientCertificate:
            //            Client certificate authentication
            //            let credential = NSURLCredential(identity: <#T##SecIdentity#>, certificates: <#T##[AnyObject]?#>, persistence: <#T##NSURLCredentialPersistence#>)
            credential = nil
    
    
        case NSURLAuthenticationMethodServerTrust:
            //            Server trust authentication
            if let serverTrustExists = challenge.protectionSpace.serverTrust {
                credential = NSURLCredential(trust: serverTrustExists)
            }
            else {
                credential = nil
            }
    
        default:
            credential = nil
        }
    
        return credential
    }