swift - 在 Swift 中为 SOAP POST 从 NSURLConnection 迁移到 NSURLSession

标签 swift soap nsurlconnection nsurlsession nsurlsessiondatatask

我正在尝试从 NSURLConnection 转移到 NSURLSession 以获取 SOAP 帖子,但 NSURLSessionDataDelegate 似乎有问题。

这是 NSURLConnection 中的旧代码,它运行良好:

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,并按如下方式正常工作:

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,那么我将无法使其正常工作。

新代码如下:

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:

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

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

“我在 NSURLSessionDelegate didReceiveChallenge 中” “是的授权”

所以它可以正常执行 didReceiveChallenge,并且它似乎可以正常授权 HTTPS 安全证书,但是之后没有任何进一步的 react ,它没有做任何其他事情,我希望它进入 didReceiveResponse,然后进入 didReceiveData,但什么也没有进一步发生。

所以我被卡住了,我当然可以继续使用 NSURLConnection,因为它一切正常,但我想了解 NSURLSession,特别是我哪里出错了。因此,如果有人可以提供帮助,那就太好了。

谢谢

最佳答案

如果其他人遇到同样的问题,我已将其解决。问题是我没有在 didReceiveChallenge 和 didReceiveResponse 委托(delegate)中使用 completionHandler

关于swift - 在 Swift 中为 SOAP POST 从 NSURLConnection 迁移到 NSURLSession,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32863584/

相关文章:

ios - 如何在 Swift 的 AppDelegate 中初始化 NSTimer

ios - 如何以编程方式在 iOS 的恢复模式下从服务器下载内容

swift - 在 if 语句中使用 NOT 运算符时感到困惑吗?

java - 如何在 Java 中将 SOAP 消息的字节数组转换为原始 XML

php - 在 PHP 中处理 Soap 超时

PHP 和 SOAP 。更改信封

NSURLConnection sendAsynchronousRequest 在哪个线程上运行的 iOS

ios - NSURLConnection 失败,错误代码为 -1001、-1005、1004 以及 NSPOSIXErrorDomain Code=2

ios - 带有大标题导航的 UITableView UIRefreshControl 不会粘在顶部 - 它会移动

ios - 如何创建 Collection View 并以编程方式将其添加到 ViewController?