1

J'essaie de passer de NSURLConnection à NSURLSession pour un post SOAP, mais semble avoir des problèmes avec NSURLSessionDataDelegate.Passage de NSURLConnection à NSURLSession pour SOAP POST dans Swift

Voici l'ancien code NSURLConnection qui fonctionne très bien:

let soapMessage = "<?xml version='1.0' encoding='UTF-8'?><SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ns1='http://tempuri.org/'><SOAP-ENV:Body><ns1:get_Countries/></SOAP-ENV:Body></SOAP-ENV:Envelope>" 
    print("Soap Packet is \(soapMessage)") 

    let urlString = "https://example.com/Service.svc" 
    let url = NSURL(string: urlString) 
    let theRequest = NSMutableURLRequest(URL: url!) 
    let msgLength = String(soapMessage.characters.count) 

    theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type") 
    theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length") 
    theRequest.addValue("http://tempuri.org/IService/get_Countries", forHTTPHeaderField: "SoapAction") 
    theRequest.HTTPMethod = "POST" 
    theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) 
    print("Request is \(theRequest.allHTTPHeaderFields!)") 

    let connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: false) 
    connection?.start() 

Ce code utilise ensuite NSURLConnectionDelegate, et fonctionne bien comme suit:

func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) { 
    MutableData.length = 0; 
    let httpresponse = response as? NSHTTPURLResponse 
    print("status \(httpresponse?.statusCode)") 
    //print("headers \(httpresponse?.allHeaderFields)") 
} 

func connection(connection: NSURLConnection!, didReceiveData data: NSData!) { 
    MutableData.appendData(data) 
} 


func connection(connection: NSURLConnection, didFailWithError error: NSError) { 
    NSLog("Error with Soap call: %@", error) 

} 

func connectionDidFinishLoading(connection: NSURLConnection!) { 
    let xmlParser = NSXMLParser(data: MutableData) 
    xmlParser.delegate = self 
    xmlParser.parse() 
    xmlParser.shouldResolveExternalEntities = true 
} 

func connection(connection: NSURLConnection, willSendRequestForAuthenticationChallenge challenge: NSURLAuthenticationChallenge) { 
    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust && challenge.protectionSpace.host == "example.com" { 
     NSLog("yep") 
     let credential = NSURLCredential(trust: challenge.protectionSpace.serverTrust!) 
     challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge) 
    } else { 
     NSLog("nope") 
     challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge) 
    } 
} 

Alors que le code tout fonctionne bien, et est juste pour référence afin que vous puissiez voir ce que j'ai fait dans le passé, et le fait que l'API fonctionne réellement! Cependant, si je passe à utiliser NSURLSession et NSURLSessionDataDelegate à la place, je ne peux pas le faire fonctionner correctement.

Voici donc le nouveau code:

let soapMessage = "<?xml version='1.0' encoding='UTF-8'?><SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ns1='http://tempuri.org/'><SOAP-ENV:Body><ns1:get_Countries/></SOAP-ENV:Body></SOAP-ENV:Envelope>" 
    print("Soap Packet is \(soapMessage)") 

    let urlString = "https://example.com/Service.svc" 
    let url = NSURL(string: urlString) 
    let theRequest = NSMutableURLRequest(URL: url!) 
    let msgLength = String(soapMessage.characters.count) 

    theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type") 
    theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length") 
    theRequest.addValue("http://tempuri.org/IService/get_Countries", forHTTPHeaderField: "SoapAction") 
    theRequest.HTTPMethod = "POST" 
    theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) 
    print("Request is \(theRequest.allHTTPHeaderFields!)") 

let config = NSURLSessionConfiguration.defaultSessionConfiguration() 
let session = NSURLSession(configuration:config, delegate: self, delegateQueue: NSOperationQueue.mainQueue()) 
let task = session.dataTaskWithRequest(theRequest) 
task.resume() 

Mes délégués J'utilise sont NSURLSessionDelegate, NSURLSessionDataDelegate:

func URLSession(session: NSURLSession, didReceiveChallenge challenge: NSURLAuthenticationChallenge, completionHandler: (NSURLSessionAuthChallengeDisposition, NSURLCredential?) -> Void) { 

    print("Am in NSURLSessionDelegate didReceiveChallenge") 

    if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust && challenge.protectionSpace.host == "example.com" { 
     NSLog("yep authorised") 
     let credential = NSURLCredential(trust: challenge.protectionSpace.serverTrust!) 
     challenge.sender!.useCredential(credential, forAuthenticationChallenge: challenge) 
    } else { 
     NSLog("nope") 
     challenge.sender!.performDefaultHandlingForAuthenticationChallenge!(challenge) 
    } 

} 
func URLSessionDidFinishEventsForBackgroundURLSession(session: NSURLSession) { 
    print("Am in URLSessionDidFinishEventsForBackgroundURLSession") 
    let xmlParser = NSXMLParser(data: MutableData) 
    xmlParser.delegate = self 
    xmlParser.parse() 
    xmlParser.shouldResolveExternalEntities = true 
} 
func URLSession(session: NSURLSession, didBecomeInvalidWithError error: NSError?) { 
    print("error of \(error)") 
} 

func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { 
    print("Am in didReceiveResponse") 
    MutableData.length = 0 
} 


func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveData data: NSData) { 
    print("Am in didReceiveData") 
    MutableData.appendData(data) 
} 

func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) { 
    print("error of \(error)") 
} 

Alors, quand je lance le code, je reçois la sortie:

"Je suis dans NSURLSessionDelegate didReceiveChallenge" "yep autorisé"

Donc ça devient très bien didReceiveChallenge, et il semble bien autoriser le certificat sécurisé HTTPS, mais alors rien ne se passe plus, il ne fait rien d'autre, je m'attendrais à ce qu'il passe à didReceiveResponse puis à didReceiveData, mais rien d'autre arrive du tout. Donc, je suis coincé, je pourrais bien sûr continuer et utiliser NSURLConnection comme tout fonctionne bien, mais je voudrais comprendre le NSURLSession, et particulièrement où je me trompe. Donc, si quelqu'un peut aider ce serait génial.

Merci

Répondre

1

Au cas où quelqu'un d'autre a le même problème, je triés cela. La question était que je n'utilisais pas le completionHandler dans les didReceiveChallenge et didReceiveResponse délégués

+0

Pouvez-vous poster la réponse Si vous avez travaillé dehors.Please? J'ai vraiment besoin d'une aide aussi. –

0
func URLSession(session: NSURLSession, dataTask: NSURLSessionDataTask, didReceiveResponse response: NSURLResponse, completionHandler: (NSURLSessionResponseDisposition) -> Void) { 

completionHandler (NSURLSessionResponseDisposition.Allow) //.Cancel,If vous voulez arrêter le téléchargement }