Swift: How to consume SOAP using Alamofire?

Well, SOAP is kinda old. But if for some reason you need to use it, here is how.

1. Create empty “Single View” project, you can call it “Swift-SOAP-with-Alamofire”
2. Create file named “Podfile” inside, your directory should look like this:
Zrzut ekranu 2016-08-04 o 12.31.15
3. Open “Podfile” and add following content:


target 'Swift-SOAP-with-Alamofire' do
pod 'Alamofire'
pod 'SWXMLHash'
pod 'AEXML'
pod 'StringExtensionHTML'

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|

4. From terminal execute “pod install” (if you don’t have or don’t know what this command does, feel free to google)

5. After command is done, you should see new “Swift-SOAP-with-Alamofire.xcworkspace” file, close your project and open this one instead.

6. At top of your ViewController.swift file add:

import Alamofire
import SWXMLHash
import StringExtensionHTML
import AEXML

7. Below, add new structure for your country:

struct Country {
    var name:String = ""

Your ads will be inserted here by

Easy Plugin for AdSense.

Please go to the plugin admin page to
Paste your ad code OR
Suppress this ad slot.

8. Inside ViewController create new function:

func getCountries(completion: (result: [Country]) -> Void) -> Void {
        var result = [Country]()
        let soapRequest = AEXMLDocument()
        let envelopeAttributes = ["xmlns:SOAP-ENV" : "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:ns1" : "http://www.webserviceX.NET"]
        let envelope = soapRequest.addChild(name: "SOAP-ENV:Envelope", attributes: envelopeAttributes)
        let body = envelope.addChild(name: "SOAP-ENV:Body")
        body.addChild(name: "ns1:GetCountries")
        let soapLenth = String(soapRequest.xmlString.characters.count)
        let theURL = NSURL(string: "http://www.webservicex.net/country.asmx")
        let mutableR = NSMutableURLRequest(URL: theURL!)
        mutableR.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
        mutableR.addValue("text/html; charset=utf-8", forHTTPHeaderField: "Content-Type")
        mutableR.addValue(soapLenth, forHTTPHeaderField: "Content-Length")
        mutableR.HTTPMethod = "POST"
        mutableR.HTTPBody = soapRequest.xmlString.dataUsingEncoding(NSUTF8StringEncoding)
            .responseString { response in
                if let xmlString = response.result.value {
                    let xml = SWXMLHash.parse(xmlString)
                    let body =  xml["soap:Envelope"]["soap:Body"]
                    if let countriesElement = body["GetCountriesResponse"]["GetCountriesResult"].element {
                        let getCountriesResult = countriesElement.text!
                        let xmlInner = SWXMLHash.parse(getCountriesResult.stringByDecodingHTMLEntities)
                        for element in xmlInner["NewDataSet"]["Table"].all {
                            if let nameElement = element["Name"].element {
                                var countryStruct = Country()
                                countryStruct.name = nameElement.text!
                    completion(result: result)
                    print("error fetching XML")

Where actual magic happens.

9. Open your Info.plist as “Code view” and add this to allow loading from HTTP (unless your server has SSL working):






10. Just call:

        self.getCountries { (result) in

and your result will be populated.

You can checkout example project from github at:

Keep in mind that my code is only a way to use, for real apps, you should for example use guard instead of multiple “if let”.

1 comment

Leave a Reply