2016-04-30 1 views
0

Lorsque session est défini comme .init(configuration:..., delegate:self, delegateQueue:NSOperationQueue.mainQueue()) pour la redirection du serveur proxy, NSURLSessionDataTask.resume() n'aboutit pas à l'exécution de task. Lorsque session est défini comme .sharedSession(), task s'exécute comme prévu.Swift 2 nil NSURLSessionDataTask lors de l'ajout de la configuration

** kCFStreamPropertyHTTPProxyHost etc. ont été dépréciées. Peut-être que cela affecte NSURLSessionConfiguration d'une manière qui empêche l'exécution de 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() 
     . 
     . 
     . 
} 

Répondre

0

Réglage de la configuration

Dans la plupart des cas, la configuration par défaut fonctionne à moins que vous avez besoin quelque chose de spécial.

let sessionConfiguration = NSURLSessionConfiguration.defaultSessionConfiguration() 

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

Pls se référer à la documentation d'Apple: https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSURLSession_class/#//apple_ref/doc/uid/TP40013435-CH1-SW7

réponse Redirect

NSURLSessionDelegate a la fonction mentionnée ci-dessous qui est appelée quand une redirection arrive.

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 
} 

Il y a un paramètre appelé request qui contient le nouveau URLRequest. Maintenant, vous devez lancer une nouvelle tâche de session avec cette nouvelle demande

Défi

Cette fonction fait partie de NSURLSessionDelegate

Chaque fois que défi est reçu la fonction suivante est appelée. Selon le type de défi, vous devez le gérer de manière appropriée.

Voir le code commenté NSURLAuthenticationMethodHTTPBasic et 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 
} 
+0

Merci. Le problème était que puisque .resume() attendait que tout finisse, il continuait sur une variable tout ce qui obtient sa valeur dans la tâche. Je peux donc travailler dans son propre fil et maintenant cela fonctionne. Je ne peux pas, cependant, obtenir le proxy pour travailler. Je sais que la mise en œuvre fonctionne parce que je reçois un 407, mais le nom d'utilisateur et pw ne fonctionnent pas. – dbconfession

+0

Veuillez voir la réponse mise à jour (section Challenge). Dans votre cas, le défi est lancé qui doit être traité – user1046037