以下是我使用我的集成密钥,用户名和密码向我的Web服务发送SOAP消息的代码。我能够获得响应并将其一直解析为foundCharacters。
现在我需要存储在解析后的响应中找到的两个元素,以便稍后我可以将它们用于另一个请求。
我一直在寻找各种教程,但我无法理解这些教程,因为大多数都是关于本地存储的XML文件,而不是真正的WebService。
class LoginCentralViewController: UIViewController, XMLParserDelegate, NSURLConnectionDelegate {
var chaveWS = ChaveWebService().chave()
var mutableData:NSMutableData = NSMutableData()
var currentElement:NSString = ""
@IBAction func btnAcessarACTION(_ sender: Any) {
let soapMessage = "<soapenv:Envelope xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema' xmlns:soapenv='http://schemas.xmlsoap.org/soap/envelope/' xmlns:log='LoginCentral'><soapenv:Header/><soapenv:Body><log:LoginCentral soapenv:encodingStyle='http://schemas.xmlsoap.org/soap/encoding/'><Autenticacao xsi:type='urn:Autenticacao' xmlns:urn='urn:RouterBoxMobile'><ChaveIntegracao xsi:type='xsd:string'>\(chaveWS)</ChaveIntegracao></Autenticacao><DadosLoginCentral xsi:type='urn:DadosLoginCentral' xmlns:urn='urn:RouterBoxMobile'><Usuario xsi:type='xsd:string'>wagner</Usuario><Senha xsi:type='xsd:string'>mudar123</Senha></DadosLoginCentral></log:LoginCentral></soapenv:Body></soapenv:Envelope>"
let urlString = "https://example.com?wsdl"
let url = NSURL (string: urlString)
let theRequest = NSMutableURLRequest(url: url! as URL)
let msgLength = soapMessage.characters.count
theRequest.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
theRequest.addValue(String(msgLength), forHTTPHeaderField: "Content-Length")
theRequest.httpMethod = "POST"
theRequest.httpBody = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false)
let connection = NSURLConnection(request: theRequest as URLRequest, delegate: self, startImmediately: true)
connection!.start()
if (connection != nil) {
var mutableData : Void = NSMutableData.initialize()
}
print("passou")
}
override func viewDidLoad() {
super.viewDidLoad()
}
func connection(_ connection: NSURLConnection!, didReceiveResponse response: URLResponse!) {
mutableData.length = 0;
print("passou aqui tbm")
}
func connection(_ connection: NSURLConnection!, didReceiveData data: NSData!) {
mutableData.append(data as Data)
}
func connectionDidFinishLoading(_ connection: NSURLConnection!) {
let response = NSString(data: mutableData as Data, encoding: String.Encoding.utf8.rawValue)
let xmlParser = XMLParser(data: mutableData as Data)
xmlParser.delegate = self
xmlParser.parse()
xmlParser.shouldResolveExternalEntities = true
//print(response)
}
//XMLParser
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
currentElement = elementName as NSString
//print(elementName)
}
func parser(_ parser: XMLParser, foundCharacters string: String) {
if currentElement == "LoginCentralResponse" {
print(currentElement, string)
}
print(currentElement, string)
}
}
以下是我需要存储和重用的解析响应:
ClientCode : 8
Permissions : 70,73,77,75,71,72
答案 0 :(得分:3)
我发现您要在应用中存储凭据。通过编写文件,无需在XML中存储此类文件。您可以使用Keychain
存储此类敏感数据,您可以随时从Keychain
接收更多HTTP请求。它安全可靠。
这是我使用的钥匙串库
https://github.com/marketplacer/keychain-swift
另一个建议是,您不需要像这样解析XML这样的困难,请尝试使用它。
https://github.com/drmohundro/SWXMLHash
您的SOAP Web服务代码似乎已过时。它是一种罕见的网络服务,我们大部分时间都不会使用它和罕见的文档。现在,人们正在转向REST。您正在使用在iOS 8中弃用的NSURLConnection
。因此,让我们开始使用URLSession
。我会在这里使用Delegate Pattern
。我让你的答案非常简单,让你明白。您可以更改任何想要处理响应的内容。
所以,我有两个Swift类。一个是ViewController.swift
,另一个是SOAPService.swift
。
以下是我们将如何使用委托模式处理SOAPService。
import Foundation
import SWXMLHash
// At here you define your constants at global variables, or you can use structs
public let verify_token = "VerifyToken"
public let WSDL_URL = "https://api.example.com/services?wsdl"
public let BASE_URL = "https://api.example.com/"
public let VERIFY_TOKEN = BASE_URL + "VerifyToken"
// Creating protocol for data transfering
protocol SOAPServiceProtocol{
func didSuccessRequest(results : String, requestName : String)
func didFailRequest(err : String, requestName : String)
}
// I have extended the URLSessionDelegate and URLSessionTaskDelegate for passing TLS, so you might not needed until you handle HTTPS
class SOAPService : NSObject, URLSessionDelegate, URLSessionTaskDelegate{
// Here the initialization of delegate pattern to transfer data between classes
var delegate : SOAPServiceProtocol
init(delegate : SOAPServiceProtocol){
self.delegate=delegate
}
func post(wsdlURL : String, soapAction : String, soapMessage : String, serviceName : String, method : String){
// Here your request configurations
var request = URLRequest(url: URL(string: wsdlURL)!)
let msgLength = String(soapMessage.characters.count)
// Configure your soap message here
let data = soapMessage.data(using: String.Encoding.utf8, allowLossyConversion: false)
// Setting HTTP Header,Body and Method
request.httpMethod = method
request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue(msgLength, forHTTPHeaderField: "Content-Length")
request.addValue(soapAction, forHTTPHeaderField: "SOAPAction")
request.httpBody = data
// URLSession configuration such as TIME OUT,etc
let urlconfig = URLSessionConfiguration.default
urlconfig.timeoutIntervalForRequest = 15
urlconfig.timeoutIntervalForResource = 15
// Initiating URLSession before making a request, I will use default here
var session = URLSession.shared
session = URLSession(configuration: urlconfig, delegate: nil, delegateQueue: nil)
// Start HTTP Request
let task = session.dataTask(with: request) {
data, response, error in
if error != nil {
// If error include,return fail
self.delegate.didFailRequest(err: "Request failed", requestName: serviceName)
return
}
guard let datastring = String(data: data!, encoding:String.Encoding(rawValue: String.Encoding.utf8.rawValue)) else{
return self.delegate.didFailRequest(err: "No Data", requestName: verify_token)
}
let xml = SWXMLHash.parse(datastring)
guard let xmlResult : String = xml["soap:Envelope"]["soap:Body"]["\(serviceName)Response"]["\(serviceName)Result"].element?.text else{
print("XML is NIL")
self.delegate.didFailRequest(err: "XML is NIL", requestName: verify_token)
return
}
// when parsing complete return the parse result
self.delegate.didSuccessRequest(results: xmlResult, requestName: verify_token)
}
task.resume()
}
// Start Writing Your SOAP Services and messages HERE
func doVerify(userName : String, password : String, methodName : String){
let soapMessage = String(format:"<?xml version=\"1.0\" encoding=\"UTF-8\"?><SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"https://api.example.com/\"><SOAP-ENV:Body><ns1:VerifyToken><ns1:UserName>%@</ns1:UserName><ns1:Password>%@</ns1:Password></ns1:VerifyToken></SOAP-ENV:Body></SOAP-ENV:Envelope>",userName,password)
post(wsdlURL: WSDL_URL, soapAction: VERIFY_TOKEN, soapMessage: soapMessage, serviceName: verify_token, method: "POST")
}
}
因此,我们将使用 URLSession 处理 SOAP 网络服务。
那么,我们如何从ViewController获取响应数据?
这很容易。我们在这里实施协议方法。
import UIKit
class ViewController: UIViewController, SOAPServiceProtocol{
var soapService : SOAPService?
override func viewDidLoad() {
super.viewDidLoad()
// You need to initialize the SOAP Service to call SOAP Web Service.
soapService = SOAPService(delegate: self)
// 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 doVerify(sender : AnyObject){
// Here I started HTTP Request
soapService?.doVerify(userName: "Thiha6245", password: "dsadafwa", methodName: verify_token)
}
// Here you implement the results which success
func didSuccessRequest(results : String, requestName: String) {
print("Results : \(results)")
switch requestName {
case verify_token:
// do handling xml parsing from result to model object and get data from model
break
default :
break
}
}
// Here you implement the failure
func didFailRequest(err: String, requestName: String) {
print("Error : \(err)")
switch requestName {
case verify_token:
// do error handling here // Request TIME OUT,Internet connection error or data error,etc
break
default :
break
}
}
}
什么是SOAP消息?像REST一样,我们必须向每个人发送参数 特定服务权?
eg. "www.api.com/services/verifytoken?username=Thiha&password=dwadwdada"
(BASE_URL/SOAPAction?ParamName1=""&ParamName2="")
[GET Request in REST Web Service]
为了在SOAP中请求HTTP,您必须编写SOAP消息 为了让SOAP Web服务理解
<?xml version=\"(Here your SOAP Version)\" encoding=\"UTF-8\"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"(Your API Base URL)/\">
<SOAP-ENV:Body>
<ns1:(SOAPAction)>
<ns1: ParamName1>""</ns1: ParamName1>
<ns1: ParamName2>""</ns1: ParamName2>
</ns1:(SOAPAction)>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
我希望它可以帮到你。由于您是初学者,我建议您阅读有关NSURLSession的文档以进行进一步配置,并阅读如何使用我提到的SWXMLHash解析XML。祝你好运!