我已经查看了如何通过互联网上的SOAP表格swift调用Web服务的答案,并找到了一些答案。我试图实现我在这些答案中找到的代码,但不断获得http 400状态代码。我想弄清楚我做错了什么。
我已将问题简化为视图控制器中的几行代码,如下所示,当按下UI上的按钮时,将调用代码。我试图拨打的网络服务可以在http://www.cgsapi.com/CGSWebService.asmx找到。
(要查看WSDL文件,请将?wsdl附加到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()
}
}
当我打电话给我时,知道为什么我会获得http 400状态吗?
答案 0 :(得分:8)
所以我很傻。主要的是我错过了将消息体设置为SOAP请求。我更新的更正后的代码如下:
//
// 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()
}
}
答案 1 :(得分:2)
Swift 5.2,XCode 12
我或多或少地遵循了乔治对自己的反应所采取的方法。 我认为保留一些具有最新swift和Xcode的代码示例可能对某些人有帮助:
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()
}
在ProvidedData
中,我只是假设您会以某种方式传递您的网址和信封。
除此之外,如果您希望有一个更结构化和“基于参数”的信封,并且不介意使用外部库,那么@Pulkit Kumar Singh提出的AEXML
解决方案也很有趣
答案 2 :(得分:1)
您可以使用以下代码拨打网络服务电话。
let url = NSURL(string: "https://www.google.com/")
var request:NSMutableURLRequest = NSMutableURLRequest(URL:url!)
var bodyData = "data=something"
request.HTTPMethod = "POST"
request.HTTPBody = bodyData.dataUsingEncoding(NSUTF8StringEncoding);
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue())
{
(response, data, error) in
print(response)
if let HTTPResponse = response as? NSHTTPURLResponse {
let statusCode = HTTPResponse.statusCode
if statusCode == 200 {
// Yes, Do something.
}else{
print("Error")
}
}
}
答案 3 :(得分:0)
*api calling for returning data type soap
swift 2.2. and above*
let urlForService = NSURL.init(string: "enter your url string")
let postString = String(format: "TokenId=%@&LoggedUserId=%@&UserDeviceId=%@", arguments: ["parameter value","parameter value","parameter value"])
do
{
let urlSession:NSURLSession = NSURLSession.sharedSession()
let urlRequest:NSMutableURLRequest = NSMutableURLRequest(URL: urlForService!)
urlRequest.HTTPShouldHandleCookies = false
urlRequest.timeoutInterval = 120 ;
urlRequest.HTTPMethod = "POST";
urlRequest.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
urlRequest.addValue("\(postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)?.length)", forHTTPHeaderField: "Content-Length")
urlRequest.HTTPBody = postString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)
let session = urlSession.dataTaskWithRequest(urlRequest, completionHandler: { (data, response, errorResponse) in
if errorResponse != nil {
print(errorResponse!.localizedDescription)
}
else
{
if data != nil
{
do {
if let dictionary = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers) as? NSDictionary {
let dateformaterweb = NSDateFormatter()
dateformaterweb.dateFormat = "DD/MM/YYYY"
let tempwitnohdate = dictionary.valueForKey("AllContact") as! NSArray
for i in tempwitnohdate{
if String(i.valueForKey("Birthdate")!) != ""{
let name = String(i.valueForKey("ContactName")!)
let number = String(i.valueForKey("ContactNo")!)
let temparray = String(i.valueForKey("Birthdate")!).componentsSeparatedByString("/")
let month = temparray[1]
let day = temparray[0]
let dateweb = ([temparray[0]] + [temparray[1]]).joinWithSeparator(",")
self.usercontact.append(Utility(name: name, number: number, date: dateweb, month:Int(month)!, day:Int(day)!))
}
else{
let name = String(i.valueForKey("ContactName")!)
let number = String(i.valueForKey("ContactNo")!)
let dateweb = self.formater.stringFromDate(self.date)
self.usercontactsort.append(Utility(name: name, number: number, date: dateweb, month:13, day:32))
}
}
self.usercontactsort = self.usercontactsort.sort { $0.strName.localizedStandardCompare($1.strName) == NSComparisonResult.OrderedAscending }
self.usercontact.sortInPlace{$0.monthorder < $1.monthorder}
for i in 0...self.usercontact.count - 1{
for j in i...self.usercontact.count - 1{
if self.usercontact[i].monthorder == self.usercontact[j].monthorder && i != j{
if self.usercontact[i].dayorder > self.usercontact[j].dayorder{
let temp = self.usercontact[i]
self.usercontact[i] = self.usercontact[j]
self.usercontact[j] = temp
}
}
}
}
self.finaldata = self.usercontact + self.usercontactsort
}
self.tableview.reloadData()
}
catch {
print("Error \(error)")
}
}
}
})
session.resume()
}
答案 4 :(得分:0)
请参阅此链接https://github.com/blastar/Swift-SOAP-with-Alamofire。它为您提供了一种更有条理的方式来处理肥皂与Almofire。
1.使用可可豆荚,您可以导入以下豆荚
https://cocoapods.org/知道如何设置可可豆荚
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
2。 这只是通过更有条理的almofire实现肥皂的一种方式。你必须做一个小任务来根据你的实现进行自定义
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")
}
}
}
希望它有所帮助。
答案 5 :(得分:-2)
- (BOOL)callWebService {
NSString *soapMessage = @"<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>";
// SOAP request settings
NSURL *url = [NSURL URLWithString:@"http://www.cgsapi.com/CGSWebService.asmx"];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSURLSession *session = [NSURLSession sharedSession];
NSError *error;
request.HTTPMethod = @"POST";
request.HTTPBody = [soapMessage dataUsingEncoding:NSUTF8StringEncoding];
[request addValue:@"www.cgsapi.com" forHTTPHeaderField:@"Host"];
[request addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request addValue:[NSString stringWithFormat:@"%i", soapMessage.length] forHTTPHeaderField:@"Content-Length"];
[request addValue:@"http://www.cgsapi.com/GetSystemStatus" forHTTPHeaderField:@"SOAPAction"];
NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSLog(@"response: %@", response);
NSString *output = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(@"output: %@", output);
if (error !=nil) {
NSLog(@"error: %i %@", error.code, error.description);
}
}];
[task resume];
return true;
}