在Swift中从NSURLConnection移至NSURLSession以进行SOAP POST [英] Moving from NSURLConnection to NSURLSession for SOAP POST in Swift

查看:89
本文介绍了在Swift中从NSURLConnection移至NSURLSession以进行SOAP POST的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从NSURLConnection移到NSURLSession进行SOAP发布,但是NSURLSessionDataDelegate似乎有问题.

I am trying to move over from NSURLConnection over to NSURLSession for a SOAP post, but seem to have issues with the NSURLSessionDataDelegate.

这是NSURLConnection中的旧代码,可以很好地工作:

Here is the old code in NSURLConnection that works fine:

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()

然后,此代码使用NSURLConnectionDelegate,并且工作正常,如下所示:

This code then uses NSURLConnectionDelegate, and works fine as follows:

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

这样,所有代码都可以正常工作,仅供参考,这样您就可以了解我过去所做的事情以及API确实有效的事实!但是,如果我改用NSURLSession和NSURLSessionDataDelegate,那么我将无法正常工作.

So that code all works fine, and is just for reference so you can see what I have done in the past, and the fact that the API actually does work! However, if I move over to using NSURLSession and NSURLSessionDataDelegate instead then I cannot get it working correctly.

所以这是新代码:

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()

我正在使用的代表是NSURLSessionDelegate,NSURLSessionDataDelegate:

My delegates I am using are 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)")
}

因此,当我运行代码时,会得到输出:

So, when I run the code, I get output:

"Am in NSURLSessionDelegate didReceiveChallenge" 是授权"

"Am in NSURLSessionDelegate didReceiveChallenge" "yep authorised"

因此它可以正常执行didReceiveChallenge,并且似乎可以对HTTPS安全证书进行授权,但是此后没有发生任何其他事情,它没有做其他任何事情,我希望它进入didReceiveResponse和didReceiveData中,但是什么也没有一切都会发生.

So it's getting to didReceiveChallenge fine, and it appears to be authorising the HTTPS secure certificate fine, but then nothing further happens, it doesn't do anything else, I'd expect it to go into didReceiveResponse then didReceiveData, but nothing further happens at all.

所以我被困住了,我当然可以继续使用NSURLConnection,因为它一切正常,但是我想了解NSURLSession,尤其是我要去哪里.因此,如果有人可以提供帮助,那就太好了.

So I am stuck, I could of course continue and use NSURLConnection as it all works fine, but I'd like to understand the NSURLSession, and particulary where I am going wrong. So if anyone can help that would be great.

谢谢

推荐答案

如果其他任何人遇到相同的问题,我也会进行解决.问题是我没有在didReceiveChallenge和didReceiveResponse委托中使用completionHandler

In case anyone else has the same issue, I sorted this out. The issue was I was not using the completionHandler in the didReceiveChallenge and didReceiveResponse delegates

这篇关于在Swift中从NSURLConnection移至NSURLSession以进行SOAP POST的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆