I have looked through the answers to how to call a web service via SOAP form swift on the internet and found some answers. I have tried to implement the code I have found in those answers but continually get a http 400 status code. I am trying to figure our what I am doing wrong.
I have distilled the problem down to a few lines of code in a view controller as seen below an the code is called when a button on the UI is pressed. The web service I am trying to call can be found at http://www.cgsapi.com/CGSWebService.asmx.
(To view the WSDL file append ?wsdl to the end of the URL.)
import UIKit
class ViewController: UIViewController {
var is_SoapMessage: String = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:cgs=\"http://www.cgsapi.com/\"><soapenv:Header/><soapenv:Body><cgs:GetSystemStatus/></soapenv:Body></soapenv:Envelope>"
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.
}
@IBAction func btnClicked(sender: AnyObject)
{
var is_URL: String = "http://www.cgsapi.com/CGSWebService.asmx"
var lobj_Request = NSMutableURLRequest(URL: NSURL(string: is_URL)!)
var session = NSURLSession.sharedSession()
var err: NSError?
lobj_Request.HTTPMethod = "POST"
lobj_Request.addValue("www.cgsapi.com", forHTTPHeaderField: "Host")
lobj_Request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
//lobj_Request.addValue(String(count(is_SoapMessage)), forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("223", forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("http://www.cgsapi.com/GetSystemStatus", forHTTPHeaderField: "SOAPAction")
var task = session.dataTaskWithRequest(lobj_Request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
if error != nil
{
println("Error: " + error.description)
}
})
task.resume()
}
}
Any idea why I am getting http 400 status when I call this?
So i was being silly. The main thing was that I missed setting the body of the message to the SOAP request. My updated corrected code is below:
//
// ViewController.swift
// TestWebServiceSoap
//
// Created by George M. Ceaser Jr on 6/2/15.
// Copyright (c) 2015 George M. Ceaser Jr. All rights reserved.
//
import UIKit
class ViewController: UIViewController {
var is_SoapMessage: String = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:cgs=\"http://www.cgsapi.com/\"><soapenv:Header/><soapenv:Body><cgs:GetSystemStatus/></soapenv:Body></soapenv:Envelope>"
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.
}
@IBAction func btnClicked(sender: AnyObject)
{
var is_URL: String = "http://www.cgsapi.com/CGSWebService.asmx"
var lobj_Request = NSMutableURLRequest(URL: NSURL(string: is_URL)!)
var session = NSURLSession.sharedSession()
var err: NSError?
lobj_Request.HTTPMethod = "POST"
lobj_Request.HTTPBody = is_SoapMessage.dataUsingEncoding(NSUTF8StringEncoding)
lobj_Request.addValue("www.cgsapi.com", forHTTPHeaderField: "Host")
lobj_Request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
lobj_Request.addValue(String(count(is_SoapMessage)), forHTTPHeaderField: "Content-Length")
//lobj_Request.addValue("223", forHTTPHeaderField: "Content-Length")
lobj_Request.addValue("http://www.cgsapi.com/GetSystemStatus", forHTTPHeaderField: "SOAPAction")
var task = session.dataTaskWithRequest(lobj_Request, completionHandler: {data, response, error -> Void in
println("Response: \(response)")
var strData = NSString(data: data, encoding: NSUTF8StringEncoding)
println("Body: \(strData)")
if error != nil
{
println("Error: " + error.description)
}
})
task.resume()
}
}
Swift 5.2, XCode 12
I followed more or less the approach that George did on his self response. I think that leaving a sample of code with the latest swift and Xcode may be helpful for some:
private func exampleSoapRequest() {
let url = URL(string: ProvidedData.urlString)!
let request = NSMutableURLRequest(url: url)
request.httpMethod = "POST"
request.httpBody = ProvidedData.envelope.data(using: .utf8)
request.addValue(String(ProvidedData.envelope.count), forHTTPHeaderField: "Content-Length")
request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue("<PUT HERE YOUR SOAP ACTION IF NEEDED>", forHTTPHeaderField: "SOAPAction")
let task = URLSession.shared
.dataTask(with: request as URLRequest,
completionHandler: { data, response, error in
guard error == nil else {
// Handle the error
print(error)
}
guard let data = data else {
return
}
// Continue checking response or data...
})
task.resume()
}
In the ProvidedData
, I just assumed you're gonna pass somehow your url and envelope.
In addition to that, if you want to have a more structured and "parameter based" envelope and you don't mind using external libraries, the solution with AEXML
proposed by @Pulkit Kumar Singh is also quite interesting.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With