Reputation: 717
I'm passing a SOAP message to a publicly available web service in swift. I can see that I am getting a SOAP response back and I am attempting to parse this using an NSXMLParser.
I was expecting to make use of the parser method which has the foundCharacters parameter - but this is only called once and only contains the string : "Error"
I want to be able to access the result which I believe should be contained within the CelsiusToFahrenheitResult tag
The web service I'm calling and the SOAP messages can be found here.
I can see that the response contains the following elements:
But why isn't the values held in these also being printed?
A similar question can be found here: Parsing SOAP response using NSXMLParser with Swift but this lacks a complete answer.
Full code for my view controller which calls the web service on button press:
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate {
var mutableData:NSMutableData = NSMutableData.alloc()
@IBOutlet weak var button: UIButton!
@IBOutlet weak var textfield: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
// These counts are just for my own reference - checking these later.
var didStartElement = 0
var didEndElement = 0
var foundCharacters = 0
func callWebService(){
// This would likely be taken from an input.
var celcius = "10";
var soapMessage = "<?xml version='1.0' encoding='utf-8'?><soap:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/'><soap:Body><CelsiusToFahrenheit xmlns='http://www.w3schools.com/webservices/tempconvert.asmx'><Celsius>\(celcius)</Celsius></CelsiusToFahrenheit></soap:Body></soap:Envelope>"
println(soapMessage);
var urlString = "http://www.w3schools.com/webservices/tempconvert.asmx?op=CelsiusToFahrenheit"
var url = NSURL(string: urlString)
var theRequest = NSMutableURLRequest(URL: url!)
var msgLength = String(count(soapMessage))
theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
theRequest.addValue(msgLength, forHTTPHeaderField: "Content-Length")
theRequest.addValue("http://www.w3schools.com/webservices/CelsiusToFahrenheit", forHTTPHeaderField: "SOAPAction")
theRequest.HTTPMethod = "POST"
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
// Do NOT call start since the above call will start the connection
}
@IBAction func convertButtonClicked(sender: AnyObject) {
callWebService();
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
println(response);
if let httpResponse = response as? NSHTTPURLResponse {
// Just printing the status code here.
println("error \(httpResponse.statusCode)")
}
// We got a response to set the length of the data to zero since we will be adding to this
// if we actually got any data back.
mutableData.length = 0;
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
}
// Parse the result right after loading
func connectionDidFinishLoading(connection: NSURLConnection!) {
println(mutableData)
var xmlParser = NSXMLParser(data: mutableData)
xmlParser.delegate = self
xmlParser.shouldProcessNamespaces = false
xmlParser.shouldReportNamespacePrefixes = false
xmlParser.shouldResolveExternalEntities = false
xmlParser.parse()
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [NSObject : AnyObject]) {
didStartElement += 1
// Can see elements in the soap response being printed.
println(elementName);
}
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
didEndElement += 1
}
func parser(parser: NSXMLParser, foundCharacters string: String?) {
foundCharacters += 1
// This prints "Error"
println("found chars: \(string!)");
}
}
Upvotes: 1
Views: 2545
Reputation: 1993
The problem is not with NSXMLParser
. You have a problem with your request soap message, make sure to use the correct namespace:
WAS:
<CelsiusToFahrenheit xmlns='http://www.w3schools.com/webservices/tempconvert.asmx'>
FIXED:
<CelsiusToFahrenheit xmlns="http://www.w3schools.com/webservices/">
Upvotes: 1