ylliX - Online Advertising Network Swift: How to consume SOAP using Alamofire? - Yet Another Programmer's Blog

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:

use_frameworks!

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

post_install do |installer|
  installer.pods_project.targets.each do |target|
    target.build_configurations.each do |config|
      config.build_settings['CONFIGURATION_BUILD_DIR'] = '$PODS_CONFIGURATION_BUILD_DIR'
    end
  end
end

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

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)
        
        Alamofire.request(mutableR)
            .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!
                                result.append(countryStruct)
                            }
                        }
                    }
                    completion(result: result)
                }else{
                    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):

<key>NSAppTransportSecurity</key>

<dict>

<key>NSAllowsArbitraryLoads</key>

<true/>

</dict>

10. Just call:

        self.getCountries { (result) in
            print(result)
        }

and your result will be populated.

You can checkout example project from github at:
https://github.com/blastar/Swift-SOAP-with-Alamofire

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”.

4 thoughts on “Swift: How to consume SOAP using Alamofire?

Leave a Reply