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:
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”.
OMG!!! I’ve been looking for something like this for weeks! Thank you, thank you very much!!!!!!!
Excellent. You saved my lot of times…
Please update code for swift 3.x
There is a pod library which makes the things easier
https://github.com/ShakeebM/AlamofireSoap