Update (13 November, 2017): Updated codes for Xcode 9 and swift 4.0
Update (25 March, 2016): I’ve updated codes for Xcode 7 and swift 2.0
Update (16 September, 2016): Code updated for Xcode 7.2.1 and swift 2.1.1
Today I’ll show you how to develop SWIFT based application that communicates with a web service using SOAP.
We’ll use following web service and convert temperature from celcious to fahrenheit:
http://www.webservicex.net/ConvertTemperature.asmx
If you are new to SOAP, then I’d recommend you to learn it from the following link:
http://www.w3schools.com/webservices/ws_soap_intro.asp
And to learn the basics of swift, you can read apple’s documentation by clicking here.
Requirements: Basic understanding of Web services, SOAP and swift.
First open Xcode 9 (or later version) and create a new project named “Temperature Converter”. Select swift as language from first dialog box. Created project will contain ViewController.swift, Main.storyboard and other files.

Step 1: Add delegation names that we’ll be delegating through out this project. We’ll delegate:UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
class ViewController: UIViewController, UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate { @IBOutlet var txtCelsius : UITextField @IBOutlet var txtFahrenheit : UITextField @IBAction func actionConvert(sender : AnyObject) { } override func viewDidLoad() { super.viewDidLoad() } override func didReceiveMemoryWarning() { super.didReceiveMemoryWarning() } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
class ViewController: UIViewController, UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate { var mutableData:NSMutableData = NSMutableData() var currentElementName:String = "" @IBOutlet var txtCelsius : UITextField! @IBOutlet var txtFahrenheit : UITextField! @IBAction func actionConvert(sender : AnyObject) { } ... ... |
Step 3: Modify the actionConvert method to let it get user input from Celcius textfield and make a request to server using post method. The full actionConvert method will look like following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
@IBAction func actionConvert(sender : AnyObject) { let celcius = txtCelsius.text let 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><ConvertTemp xmlns='http://www.webserviceX.NET/'><Temperature>\(celcius!)</Temperature><FromUnit>degreeCelsius</FromUnit><ToUnit>degreeFahrenheit</ToUnit></ConvertTemp></soap:Body></soap:Envelope>" let urlString = "http://www.webservicex.net/ConvertTemperature.asmx" let url = URL(string: urlString) let theRequest = NSMutableURLRequest(url: url!) let msgLength = soapMessage.characters.count theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type") theRequest.addValue(String(msgLength), forHTTPHeaderField: "Content-Length") theRequest.httpMethod = "POST" theRequest.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false) // or false let connection = NSURLConnection(request: theRequest as URLRequest, delegate: self, startImmediately: true) connection!.start() } |
Step 4: Using following 3 methods we’ll delegate with NSURLConnection. First 2 methods will save data received from server in mutableData variable. The last method will start NSXMLparser to parse SOAP message.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
func connection(_ connection: NSURLConnection, didReceive response: URLResponse) { mutableData = NSMutableData() } func connection(_ connection: NSURLConnection, didReceive data: Data) { self.mutableData.append(data) } func connectionDidFinishLoading(_ connection: NSURLConnection) { let xmlParser = XMLParser(data: mutableData as Data) xmlParser.delegate = self xmlParser.parse() xmlParser.shouldResolveExternalEntities = true } |
Step 5: We need 2 methods to parse SOAP message returned from server. I’ll discuss one by one so that you can understand them.
The first method is called each time a new node or element of SOAP (or XML) is parsed. We need to save this name so that we can detect each node in second method. Let’s see the first method:
1 2 3 |
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) { currentElementName = elementName } |
The second method will check the current element name and if it finds “ConvertTempResult” element, then it displays the value in Fahrenheit text field.
1 2 3 4 5 |
func parser(_ parser: XMLParser, foundCharacters string: String) { if currentElementName == "ConvertTempResult" { txtFahrenheit.text = string } } |
Now, save and run the code. If you put any numeric value in Celsius box and tap Convert button, Fahrenheit box will display the result fetched from server.
You can download the whole project from here.
Or can pull the latest project code from Github:
https://github.com/rubelbd82/soapwithswift
Best of luck!!!
Help please
i downloaded this project and it doesn’t parse anything..
help please I need this for a school project 🙂
What is the Xcode version you are using? What is the error message you are getting?
Step 5 mentions 2 methods but only one is in this article
Thank you so much. I’ve added the 2nd method.
Good to note that if only 1 character is incorrect, with Soap calls from Swift you will get, Nothing!
About parsing sections it doesn’t parse anything. My Xcode 8.1 and swift 3. i can read data only ascii so how can i parse incoming data?
Hi,
Its somehow getting the connection as False. So, its not doing any calculation & hence no result!
Please help!
Thanks!
I’ll check it come back to you soon.
After exploring a few of the articles on your blog, I honestly appreciate your technique of blogging. I added it to my bookmark site list and will be checking back in the near future. Please visit my website as well and tell me how you feel.
Is there any way to do this connection asynchronously through the dispatcher?
Hey.
nice tutorial, but in my Xcode 6 with Swift i dont have the functrion:
NSURL.URLWithString <- URLWithString is unavaible, use object constructor NSURL
Greetz
Hi,
I downloaded the project and directly got two errors. I am using Xcode version 6.3. Any Idee what I am doing wrong?
Thanks for any help!
func application
AppDelegate.swift:17:10: Objective-C method ‘application:didFinishLaunchingWithOptions:’ provided by method ‘application(_:didFinishLaunchingWithOptions:)’ conflicts with optional requirement method ‘application(_:didFinishLaunchingWithOptions:)’ in protocol ‘UIApplicationDelegate’
func parser
ViewController.swift:93:10: Objective-C method ‘parser:didStartElement:namespaceURI:qualifiedName:attributes:’ provided by method ‘parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)’ conflicts with optional requirement method ‘parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)’ in protocol ‘NSXMLParserDelegate’
Hi,
I downloaded the project and directly got two errors. I’am using Xcode version 6.3. Any Idee what I am doing wrong?
Thanks for any help!
func application
AppDelegate.swift:17:10: Objective-C method ‘application:didFinishLaunchingWithOptions:’ provided by method ‘application(_:didFinishLaunchingWithOptions:)’ conflicts with optional requirement method ‘application(_:didFinishLaunchingWithOptions:)’ in protocol ‘UIApplicationDelegate’
func parser
ViewController.swift:93:10: Objective-C method ‘parser:didStartElement:namespaceURI:qualifiedName:attributes:’ provided by method ‘parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)’ conflicts with optional requirement method ‘parser(_:didStartElement:namespaceURI:qualifiedName:attributes:)’ in protocol ‘NSXMLParserDelegate’
The following url might be useful:
http://www.raywenderlich.com/forums/viewtopic.php?f=45&t=21087
Hi ,
I am working on xcode 6.3.2
but it getting error to me
if I use the code in connection area
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection?.start()
if(connection == true) {
var mutableData : Void = NSMutableData.initialize()
println(“connect “)
}
else
{
println(“not connected “)
}
it show me not connected . Please help .
Thanks
Please, check the url that you are trying to reach is working on your browser. Also check your internet connection.
Hi
I have already checked
please see I am doing anything wrong here
var soapMessage = “”
// NSLog(“soapMessage generated is: %@”, soapMessage)
// Soap URL Works
var urlString = “http://assetwebservice.sudesi.in/service.svc”
//Below https URL does not work
var url = NSURL(string: urlString)
var theRequest = NSMutableURLRequest(URL: url!)
//Get Length of request
var msgLength = String(count(soapMessage))
// POST Header values
theRequest.addValue(“text/xml; charset=utf-8”, forHTTPHeaderField: “Content-Type”)
theRequest.addValue(msgLength, forHTTPHeaderField: “Content-Length”)
theRequest.addValue(“http://tempuri.org/IService/BindCategory”, forHTTPHeaderField: “SoapAction”)
theRequest.HTTPMethod = “POST”
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
NSLog(“Request is: %@”, theRequest.allHTTPHeaderFields!)
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection?.start()
if (connection == true) {
var mutableData : Void = NSMutableData.initialize()
}
else
{
println(“false “)
}
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
// println(“0”)
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
//println(“more > 0”)
}
func connection(connection: NSURLConnection, didFailWithError error: NSError) {
NSLog(“Error with Soap call: %@”, error)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var xmlParser = NSXMLParser(data: mutableData)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
func parser(parser: NSXMLParser, foundCharacters string: String?) {
if(!string!.isEmpty)
{
println(string)
if currentElementName == “CelsiusToFahrenheitResult” {
// txtFahrenheit.text = string
println(string)
}
}
}
Same error for me.
I don’t understand why connection is not true. My code:
var urlString = “http://www.w3schools.com/webservices/tempconvert.asmx”
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.HTTPMethod = “POST”
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion:false) // or false
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection!.start()
I tried to run this project on xCode 6.4 , but getting errors.
What is the error message you are getting?
Your code was ausum …..Thanks a ton…….I hade to make two changes though
import UIKit
class ViewController: UIViewController, UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate {
@IBOutlet weak var txtInput: UITextField!
@IBOutlet weak var txtOutput: UITextField!
var mutableData:NSMutableData = NSMutableData.alloc()
var currentElementName:NSString = “”
@IBAction func goNext(sender: AnyObject) {
//txtOutput.text = “67”
var celcius = txtInput.text
var soapMessage = “\(celcius)”
var urlString = “http://www.w3schools.com/webservices/tempconvert.asmx?op=CelsiusToFahrenheit”
var url = NSURL(string : urlString)
var theRequest = NSMutableURLRequest(URL: url!)
var msgLength = String(countElements(soapMessage))
theRequest.addValue(“text/xml; charset=utf-8”, forHTTPHeaderField: “Content-Type”)
theRequest.addValue(msgLength, forHTTPHeaderField: “Content-Length”)
theRequest.HTTPMethod = “POST”
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // or false
var connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection!.start()
connection?.start()
if let connection = connection {
connection.start()
}
else {
// handle error case
}
if (connection == true) {
var mutableData : Void = NSMutableData.initialize()
}
}
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
var xmlParser = NSXMLParser(data: mutableData)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
func parser(parser: NSXMLParser!, didStartElement elementName: String!, namespaceURI: String!, qualifiedName qName: String!, attributes attributeDict: NSDictionary!) {
currentElementName = elementName
}
func parser(parser: NSXMLParser!, foundCharacters string: String!) {
if currentElementName == “CelsiusToFahrenheitResult” {
txtOutput.text = string
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Hello! Could anyone tell me how to change this code to work in Swift 2.0?
var mutableData : Void = NSMutableData.initialize() is not in swift 2.0 allowed
what can i do ?
you can change NSMutableData.initialize() into NSMutableData()
cmiiw
Esto no funciona ni pa’lante y pa’tras
this code doesn’t work, i have been test many thing, but connection only is = false, I have been lost my time
xcode 7.2
(Swift 2.0 Xcode 7.0 beta 5)
Issue I have is with the Fahrenheit text box not refreshing unless it is clicked, but the request is made and parsed correctly…
Another way to the same end for what it is worth:
class ViewController: UIViewController, UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate {
var currentElementName : NSString = “” // used to track element name from the xml response
@IBOutlet var txtCelcius : UITextField! // input element
@IBOutlet var txtFahrenheit : UITextField! // output element
// Call Soap Service
@IBAction func actionTempConvert(sender: AnyObject) {
let celcius = txtCelcius.text // get input value
var soapMessage = “\(celcius!)”
let urlString = “http://www.w3schools.com/webservices/tempconvert.asmx” // set Service endpoint with input “Celsius”
let url = NSURL(string : urlString) // create instance of NSURL
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.HTTPMethod = “POST”
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // or false
let session = NSURLSession.sharedSession()
session.dataTaskWithRequest(theRequest) { (data, response, error) -> Void in
let xmlParser = NSXMLParser(data: data!)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}.resume()
}
// End Soap Call
// Parse it
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentElementName = elementName
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
if currentElementName == “CelsiusToFahrenheitResult” {
txtFahrenheit.text = string
}else{
}
}
// End Parsing
override func viewDidLoad() {
super.viewDidLoad()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
The following url might be useful:
http://www.wsdl2swift.com
This worked for me in Swift 2.0.
//
// ViewController.swift
// Temperature Converter
//
// Created by Farhad on 10/24/14.
// Copyright (c) 2014 Web In Dream. All rights reserved.
//
import UIKit
//Step 1: Add protocol names that we will be delegating.
class ViewController: UIViewController, UITextFieldDelegate, NSURLConnectionDelegate, NSXMLParserDelegate {
@IBOutlet weak var txtCelsius : UITextField!
@IBOutlet weak var txtFahrenheit : UITextField!
var mutableData:NSMutableData = NSMutableData.init()
var currentElementName:NSString = “”
@IBAction func actionConvert(sender : AnyObject) {
//let celcius = txtCelsius.text!
guard let celcius = txtCelsius.text where celcius != “” else {
return
}
let soapMessage = “\(celcius)”
let urlString = “http://www.w3schools.com/webservices/tempconvert.asmx?op=CelsiusToFahrenheit”
let url = NSURL(string: urlString)
let theRequest = NSMutableURLRequest(URL: url!)
//var msgLength = String(countElements(soapMessage))
theRequest.addValue(“text/xml; charset=utf-8”, forHTTPHeaderField: “Content-Type”)
theRequest.addValue(“/(soapMessage.characters.count)”, forHTTPHeaderField: “Content-Length”)
theRequest.HTTPMethod = “POST”
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // or false
let connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection!.start()
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// NSURLConnectionDelegate
// NSURL
func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!) {
mutableData.length = 0;
}
func connection(connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection!) {
let xmlParser = NSXMLParser(data: mutableData)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
}
// NSXMLParserDelegate
func parser(parser: NSXMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
currentElementName = elementName
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
//!!!if currentElementName == “CelsiusToFahrenheitResult” {
txtFahrenheit.text = string
//}
}
}
hmmm. That didn’t paste correctly. The line:
let soapMessage = “…
should be as it was in the original code, not what shows in my post above.
Thanks for the tutorial,really help for beginner learning at SOAP Web service.But the problem is can you update this to latest swift 2.1 and NSURLConnection can’t use at iOS 9.So,Can u update this tutorial in NSURLSession?Thanks.With Regards…
Hello
I got information at your blog. thanks
I try to this code running at Xcode7/iOS9/swift2 but it is not running
so Did you tried to swift2?
I m having same problem as hans
var mutableData : Void = NSMutableData.initialize() is not in swift 2.0 allowed
please do help
Just use
var mutableData:NSMutableData = NSMutableData()
Xcode 7.3.
//
// ViewController.swift
//
// Created by Linh Dao on 4/25/16.
// Copyright © 2016 Linh Dao. All rights reserved.
//
import UIKit
class ViewController: UIViewController, NSURLConnectionDataDelegate, NSXMLParserDelegate, UITextFieldDelegate {
var mutableData:NSMutableData = NSMutableData.init()
var currentElementName = “”
@IBOutlet weak var txtFah: UITextField!
@IBOutlet weak var txtCel: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func getFarenheit(celsius celsius: Int) {
let soapMessage = “\(celsius)”
let urlString = “http://www.w3schools.com/xml/tempconvert.asmx”
if let url = NSURL(string: urlString) {
let theRequest = NSMutableURLRequest(URL: url)
theRequest.addValue(“text/xml; charset=utf-8”, forHTTPHeaderField: “Content-Type”)
theRequest.addValue((soapMessage), forHTTPHeaderField: “Content-Length”)
theRequest.HTTPMethod = “POST”
theRequest.HTTPBody = soapMessage.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
let connection = NSURLConnection(request: theRequest, delegate: self, startImmediately: true)
connection?.start()
if connection == true {
var mutableData:Void = NSMutableData.initialize()
}
NSLog(“anc %@”, theRequest)
}
}
@IBAction func btnConvert(sender: AnyObject) {
getFarenheit(celsius: Int(txtCel.text!)!)
}
func connection(connection: NSURLConnection, didReceiveResponse response: NSURLResponse) {
mutableData.length = 0
}
func connection(connection: NSURLConnection, didReceiveData data: NSData) {
mutableData.appendData(data)
}
func connectionDidFinishLoading(connection: NSURLConnection) {
let response = NSString(data: mutableData, encoding: NSUTF8StringEncoding)
let xmlParse = NSXMLParser(data: mutableData)
xmlParse.delegate = self
xmlParse.parse()
xmlParse.shouldResolveExternalEntities = true
print(“loaded”)
}
func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentElementName = elementName
print(“2”)
}
func parser(parser: NSXMLParser, foundCharacters string: String) {
NSLog(“accc %@”, string)
if currentElementName == “CelsiusToFahrenheitResult” {
txtFah.text = string
}
}
}
Make following small changes for the downloaded project to work with Swift 2.2.1 in xCode 7.3.1:
command , Text Editing
click line numbers if you have none.
Then these small changes in file ViewController.swift:
line 22 change celcius to celsius
line 25 change string
to …” + String(celsius!) + “…
line 42, comment out
line 44, comment out
line 87, comment out
line 89, comment out
Hi,
Somebody are running this in Xcode 8 swift 3?
Thanks
Hi, here is the code for Xcode 8 swift 3,
In Swift 3 there are a few changes, for example the use of URLSession instead of NSURLConnection. Other problem was the refresh of text field fahrenheit, for this i used:
DispatchQueue.main.async {
self.txtFahrenheit.text = string
}
All code:
class ViewController: UIViewController, UITextFieldDelegate, XMLParserDelegate, URLSessionDataDelegate, URLSessionDelegate {
@IBOutlet weak var txtCelcius: UITextField!
@IBOutlet weak var txtFahrenheit: UITextField!
var mutableData:NSMutableData = NSMutableData.init()
var currentElementName:NSString = “”
@IBAction func actionConvertir(_ sender: AnyObject) {
let session = URLSession.shared // Load configuration into Session
let celcius = txtCelcius.text
let soapMessage = “\(celcius!)”
let urlString = “http://www.w3schools.com/xml/tempconvert.asmx”
let myUrl = URL(string: urlString);
var theRequest = URLRequest(url:myUrl!)
let msgLength = String(soapMessage.characters.count)
theRequest.addValue(“text/xml; charset=utf-8”, forHTTPHeaderField: “Content-Type”)
theRequest.addValue(msgLength, forHTTPHeaderField: “Content-Length”)
theRequest.httpMethod = “POST”
theRequest.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false)
let task = session.dataTask(with: theRequest as URLRequest) {
data, response, error in
if error != nil {
guard error == nil else {
print(“error : \(error)”)
return
}}
let strData = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
print(strData)
let myparser = XMLParser(data: data!)
myparser.delegate = self
myparser.parse()
myparser.shouldResolveExternalEntities = true
}
task.resume()
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
print(“————–parser1————–“)
currentElementName = elementName as NSString
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
print(“————-parser2—————“)
if currentElementName == “CelsiusToFahrenheitResult” {
DispatchQueue.main.async {
self.txtFahrenheit.text = string
}
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
}
Here’s the code I wound up with. I converted to Swift 3 and URLSession instead of NSURLConnection:
////////////////////////////////////////////////////////////////////////////////
var mutableData:NSMutableData = NSMutableData.init()
var currentElementName:NSString = “”
var soapSession = Foundation.URLSession(configuration: URLSessionConfiguration.default)
@IBOutlet weak var txtCelsius: NSTextField!
@IBOutlet weak var txtFahrenheit: NSTextField!
@IBAction func actionConvert(_ sender: AnyObject) {
let celsius = txtCelsius.stringValue
let soapMessage = “\(celsius)”
let urlString = “http://www.w3schools.com/xml/tempconvert.asmx”
let url = Foundation.URL(string: urlString)
let theRequest = NSMutableURLRequest(url: url!)
let msgLength = soapMessage.characters.count
theRequest.addValue(“application/soap+xml; charset=utf-8”, forHTTPHeaderField: “Content-Type”)
theRequest.addValue(String(msgLength), forHTTPHeaderField: “Content-Length”)
theRequest.httpMethod = “POST”
theRequest.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false) // or false
let task = soapSession.dataTask(with: theRequest as URLRequest, completionHandler: { (returnedData : Data?, response : URLResponse?, error : Error?) -> Void in
guard error == nil
else {
print(“Error: URL Session Task Failed: \(error!.localizedDescription)”)
return
}
let xmlParser = XMLParser(data: returnedData!)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
})
task.resume()
}
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
currentElementName = elementName as NSString
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
if currentElementName == “CelsiusToFahrenheitResult” {
DispatchQueue.main.async {
self.txtFahrenheit.stringValue = string
}
}
}
////////////////////////////////////////////////////////////////////////////////
I still don’t understand the XMLParser parts. Planning to work on that next.
Wow. The “soapMessage” in that code got different. It’s the same as in the original code above, just with escaped quotes instead of single ticks.
Hi Farhad,
I am new to iOS . I am using swift 4. I want to send a soap request with pass xml data (Username & Password). I tried lot of sample . But didn’t work. Can you help me. and What is soap message. can i pass Username & Password into soap message.
Thanks in advance.
You can send username and password by using header key-value pair.
Hi, I am running XCode 10.1 with Swift 4.2 and I have updated everything accordingly but I seem to be having trouble with the parsing. I’ve inspected the issue and I get the error “The operation couldn’t be completed. (NSXMLParserErrorDomain error 111.)” I’m kinda stuck on this and some help would be so greatly appreciated 🙂
Thanks!