Reputation: 14092
I created 2 helper classes for me. First for general SOAP request:
import Foundation
class ApiManager : NSObject {
var token: String
class var sharedInstance: ApiManager {
struct Static {
static var instance: ApiManager?
static var disptachToken: dispatch_once_t = 0
}
dispatch_once(&Static.disptachToken) {
Static.instance = ApiManager()
}
return Static.instance!
}
override init() {
token = ""
super.init()
}
func postSOAP(message: String, urlString: String, soapAction: String, completion: (result: NSData) -> Void) {
var url = NSURL(string: urlString)
var request = NSMutableURLRequest(URL: url!)
var msgLength = String(countElements(message))
request.addValue("text/xml; charset=utf-8", forHTTPHeaderField: "Content-Type")
request.addValue(msgLength, forHTTPHeaderField: "Content-Length")
request.addValue(soapAction, forHTTPHeaderField: "SOAPAction")
if (!token.isEmpty) {
request.addValue(".CAAUSGEX=" + token, forHTTPHeaderField: "Cookie")
}
request.HTTPMethod = "POST"
request.HTTPBody = message.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) // or false
let queue:NSOperationQueue = NSOperationQueue()
NSURLConnection.sendAsynchronousRequest(request, queue: queue, completionHandler:{ (response: NSURLResponse!, data: NSData!, error: NSError!) -> Void in
completion(result: data)
})
}
}
And second for each requests:
class ContentManager : NSObject {
private let apiManager = ApiManager.sharedInstance
class var sharedInstance: ContentManager {
struct Static {
static var instance: ContentManager?
static var token: dispatch_once_t = 0
}
dispatch_once(&Static.token) {
Static.instance = ContentManager()
}
return Static.instance!
}
override init() {
super.init()
}
func login(email: String, password: String, completion: (token: String) -> Void) {
var soapMessage = "<?xml version='1.0' encoding='UTF-8'?><SOAP-ENV:Envelope xmlns:SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/' xmlns:ns1='http://tempuri.org/'><SOAP-ENV:Body><ns1:LoginMethod><ns1:userName>" + email + "</ns1:userName><ns1:password>" + password + "</ns1:password></ns1:LoginMethod></SOAP-ENV:Body></SOAP-ENV:Envelope>"
let urlString = "https://someurl.svc/soap"
let soapAction = "http://someurl/LoginMethod"
ApiManager.sharedInstance.postSOAP(soapMessage, urlString: urlString, soapAction: soapAction) { (result) -> Void in
var error: NSError?
if let xmlDoc = AEXMLDocument(xmlData: result, error: &error) {
// prints the same XML structure as original
println(xmlDoc.xmlString)
let token = xmlDoc.root["s:Body"]["GetResponse"]["LoginTokenResult"].stringValue
println(token)
completion(token: token)
} else {
println("description: \(error?.localizedDescription)\ninfo: \(error?.userInfo)")
}
completion(token: "")
}
}
It's working but I would like to create better solution. First improve requests body. Is is to possible to create it somehow from swift class? Let's say I would have class LoginMethod and with properties userName and password and I would call some method and it would return string like this (with values where are variables):
<ns1:LoginMethod><ns1:userName>" + userName + "</ns1:userName><ns1:password>" + password + "</ns1:password></ns1:LoginMethod>
Then I would add begining of xml and end and I would have request.
Second problem is parsing xml. I found AEXML and It works great but again I would like to have something smarter. I would like to give it class and try to fill it with values from xml. My method could be enough for token but what if I have in response array of objects. Or if there are errors or other parameters.
Thanks for help.
Upvotes: 3
Views: 7973
Reputation: 2284
Although still in beta, but still covers what you're looking for and provides you with a good base that you can feel free to modify:
http://wsdl2swift.com
Disclaimer: I'm the author.
Upvotes: 5
Reputation: 15784
If you want a Easy-to-Use Soap parser, you should create soap classe from your WSDL. At this state, there is no tools for swift but you can find tools for objective-c. Before, I used WSDL2Objc to generate objective-c Classes that present a soap service (about 70% of classes are corrects). It can save you many times if you have big SOAP service.
I've just found another tool online (but premium features are not free): http://easywsdl.com/ The author says that it's compatible with Swift but I guest that we have to use Bridging Header. Normally, with Bridging Header, you can import Objective-C classes in your swift project.
Upvotes: 4