This generic SOAP client allows you to access web services using a your iOS app, Mac OS X app and Apple TV app.
With this Framework you can create iPhone, iPad, Mac OS X and Apple TV apps that supports SOAP Client Protocol. This framework able executes methods at remote web services with SOAP standard protocol.
- Support both 2001 (v1.1) and 2003 (v1.2) XML schema.
- Support array, array of structs, dictionary and sets.
- Support for user-defined object with serialization of complex data types and array of complex data types, even embedded multilevel structures.
- Supports ASMX Services, WCF Services (SVC) and now also the WSDL definitions.
- Supports Basic, Digest and NTLM Authentication, WS-Security, Client side Certificate and custom security header.
- Supports iOS Social Account to send OAuth2.0 token on the request.
- AES256 or 3DES Encrypt/Decrypt data without SSL security.
- An example of service and how to use it is included in source code.
Requirements for iOS
- iOS 8.0 and later
- Xcode 8.0 or later
- Security.framework
- Accounts.framework
- Foundation.framework
- UIKit.framework
- libxml2.dylib
Requirements for Mac OS X
- OS X 10.9 and later
- Xcode 8.0 or later
- Security.framework
- Accounts.framework
- Foundation.framework
- AppKit.framework
- Cocoa.framework
- libxml2.dylib
Requirements for Apple TV
- iOS 9.0 and later
- Xcode 8.0 or later
- Security.framework
- Foundation.framework
- UIKit.framework
- libxml2.dylib
- for WCF services, only supports basic http bindings (basicHttpBinding).
- in Mac OS X unsupported image objects, instead you can use the NSData.
-
Swift 4: the library is currently written in Objective-C and when you import the swift library you will get build errors like this
The use of Swift 3 @objc inference in Swift 4 mode is deprecated
.For silent this warning is need sets
Swift 3 @objc Inference
to default value in the the Build settings of target. but It's not all; the classes used to create requests must be declared with@objcMembers
andNSObject
, eg:class MyClass { ... } let param = MyClass() // ... // ... let soap = SOAPEngine() soap.setValue(param, forKey: "myKey") // ... // ...
the declaration of MyClass must become :
@objcMembers class MyClass: NSObject { ... }
From the new Xcode 8 is required an additional setting for the apps, if this setting does not exist you will see a log message like this:
App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
To resolve this, add few keys in info.plist, the steps are:
- Open
info.plist
file of your project. - Add a Key called
NSAppTransportSecurity
as a Dictionary. - Add a Subkey called
NSAllowsArbitraryLoads
as Boolean and set its value to YES as like following image.
ref link: http://stackoverflow.com/a/32631185/4069848
with Delegates :
import SOAPEngine64
class ViewController: UIViewController, SOAPEngineDelegate {
var soap: SOAPEngine = SOAPENgine()
override func viewDidLoad() {
soap.delegate = self
soap.actionNamespaceSlash = true
soap.setValue("Genesis", forKey: "BookName")
soap.setIntegerValue(1, forKey: "chapter")
// standard soap service (.asmx)
soap.requestURL("http://www.prioregroup.com/services/americanbible.asmx",
soapAction: "http://www.prioregroup.com/GetVerses")
}
func soapEngine(_ soapEngine: SOAPEngine!, didFinishLoadingWith dict: [AnyHashable : Any]!, data: Data!)
{
let dict = soapEngine.dictionaryValue()
print(dict)
}
}
with Block programming :
import SOAPEngine64
class ViewController: UIViewController {
var soap: SOAPEngine = SOAPENgine()
override func viewDidLoad() {
super.viewDidLoad()
soap.actionNamespaceSlash = true
soap.setValue("Genesis", forKey: "BookName")
soap.setIntegerValue(1, forKey: "chapter")
soap.requestURL("http://www.prioregroup.com/services/americanbible.asmx",
soapAction: "http://www.prioregroup.com/GetVerses",
completeWithDictionary: { (statusCode: Int?, dict: [AnyHashable: Any]?) -> Void in
let book:NSDictionary = dict! as NSDictionary
let verses = book["BibleBookChapterVerse"] as! NSArray
print(verses)
}) { (error: Error?) -> Void in
print(error!)
}
}
}
with Notifications :
import SOAPEngine64
class ViewController: UIViewController {
var soap: SOAPEngine = SOAPENgine()
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self,
selector: #selector(soapEngineDidFinishLoading(_:)),
name: NSNotification.Name.SOAPEngineDidFinishLoading,
object: nil)
soap.actionNamespaceSlash = true
soap.setValue("Genesis", forKey: "BookName")
soap.setIntegerValue(1, forKey: "chapter")
// standard soap service (.asmx)
soap.requestURL("http://www.prioregroup.com/services/americanbible.asmx",
soapAction: "http://www.prioregroup.com/GetVerses")
}
@objc func soapEngineDidFinishLoading(_ notification: NSNotification) {
let engine = notification.object as? SOAPEngine
let dict = engine()
print(dict)
}
}
Synchronous request :
import SOAPEngine64
class ViewController: UIViewController {
var soap: SOAPEngine = SOAPENgine()
override func viewDidLoad() {
super.viewDidLoad()
soap.actionNamespaceSlash = true
soap.setValue("Genesis", forKey: "BookName")
soap.setIntegerValue(1, forKey: "chapter")
// standard soap service (.asmx)
do {
let result = try soap.syncRequestURL("http://www.prioregroup.com/services/americanbible.asmx",
soapAction: "http://www.prioregroup.com/GetVerses")
print(result)
}
catch {
print(error)
}
}
}
settings for SOAP Authentication :
soap.authorizationMethod = .AUTH_BASICAUTH; // basic auth
soap.username = "my-username";
soap.password = "my-password";
settings for Social OAuth2.0 token :
// token authorization
soap.authorizationMethod = .AUTH_SOCIAL;
soap.apiKey = "1234567890"; // your apikey https://dev.twitter.com/
soap.socialName = ACAccountTypeIdentifierTwitter; // import Accounts
Encryption/Decryption data without SSL/HTTPS :
soap.encryptionType = ._ENCRYPT_AES256; // or SOAP_ENCRYPT_3DES
soap.encryptionPassword = "my-password";
Params with Attributes :
// book
var book = ["name": "Genesis"] as! NSMutableDictionary
var attr = ["order": "asc"]
// chapter
var child = soap.dictionary(forKey: "chapter", value: "1", attributes: attr)
book.addEntries(from: child!)
// book attributes
soap.setValue(book, forKey: "Book", attributes: ["rack": "2"])
it builds a request like this:
<Book rack="2">
<name>Genesis</name>
<chapter order="asc">1</chapter>
</Book>
First of all, if you note a slowdown in the response of the request, try to change the value of the property named actionNamespaceSlash
.
After, when using the method named requestWSDL
three steps are performed :
- retrieve the WSDL with an http request
- processing to identify the soapAction
- calls the method with an http request http request
this is not optimized, very slow, instead you can use the optimization below :
- retrieving manually the SOAPAction directly from WSDL (once with your favorite browser).
- use the method named requestURL instead of requestWSDL without WSDL extension.
SOAPEngine is available as a Swift package. The repository URL is valid for adding the package in your app through the Xcode.
Read the "Getting Started" guide
Read the Integrating SOAPEngine with a Swift project
Read the "Standard Installation" guide
Trial just simulator |
Single App single bundle-id |
Enterprise multi bundle-id |
---|---|---|
DOWNLOAD | BUY 12,99β¬ | BUY 77,47β¬ |