Consuming SOAP webservices from iOS

August 10, 2016
admin

Contributor: Abidur Rahman

Today, we will learn how to consume soap webservice from iOS. There are lots of tutorials on consuming RESTful web-services out there with better explanation, But there are a few tutorials on consuming SOAP web-services with a clear explanation.

So, in this tutorial, we will learn how to consume SOAP web services from iOS. Before starting code, we have to collect some information:

  • SOAP_ACTION
  • URL
  • Request XML/ SOAP_BODY/ SOAP_MESSAGE

Now, the question is how can we get these information? if your client or service provider give you all the information, you won’t need anything. But if they don’t, then follow the process given below:

Suppose, you have to consume the data from this service: http://www.w3schools.com/webservices/tempconvert.asmx

This is the URL!!

Click on it, you can see a link named “Service Description” and a list of Method Name(s). So, we can get the METHOD_NAMEs from here.

Now, click on the “Service Description”.

SOAP web services from iOS

You can see the SOAP_ACTIONs here depending on the METHOD_NAME. So, be careful to choose the SOAP_ACTION!! You can also get the Parameter List here depending on the METHOD_NAME.

Now, we need SOAP_BODY/ SOAP_MESSAGE/ REQUEST_XML.

There is an elegant and efficient SOAP browser online: http://wsdlbrowser.com/

Copy the URL of your web service, and add “?wsdl” at the end of the URL and then browse.

You should see the METHOD_NAME on the left side. Click on one of the METHOD_NAMEs which you want. You will see REQUEST_XML there. It is the SOAP_BODY or SOAP_MESSGAE.

SOAP web service from iOS

In the XML, you will find:

  • NAMESPACE name – Value of “xmlns:ns1”. If there are multiple namespaces, it will be indicated by ns1, ns2 and so on.  
  • METHOD_NAME – indicated by the 1st arrow.
  • Parameter Name(s) – indicated by the 2nd arrow.

Okay we have got all the information to consume soap web services from iOS. Let’s code !!!

Sample Project

Start a new iOS project and configure it as you please. Feel free to use your favorite IDE, but for this tutorial I’ll be using Xcode 6.4.

Create a method in your ViewController and add these “callSoapWebservice” method’s codes to your custom method.

#pragma mark SOAP Webservice Method

- (void) callSoapWebservice
{

// Copy the REQUEST_XML here as follows:
 NSString *soapMessage = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
 "<SOAP-ENV:Envelope xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ns1=\"http://www.w3schools.com/webservices/\">"
 "<SOAP-ENV:Body>"
 "<ns1:CelsiusToFahrenheit>"
 "<ns1:Celsius>50</ns1:Celsius>"
 "</ns1:CelsiusToFahrenheit>"
 "</SOAP-ENV:Body>"
 "</SOAP-ENV:Envelope>"];
 
 //Now create a request to the URL
 
 NSURL *url = [NSURL URLWithString:@"http://www.w3schools.com/webservices/tempconvert.asmx"]; // Copy here the URL
 NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
 
 NSString *msgLength = [NSString stringWithFormat:@"%lu", (unsigned long)[soapMessage length]];
 
 
 //add required headers to the request
 
 [theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
 
 [theRequest addValue: @"http://www.w3schools.com/webservices/CelsiusToFahrenheit" forHTTPHeaderField:@"SOAPAction"]; // copy here the SOAP_ACTION
 
 [theRequest addValue: msgLength forHTTPHeaderField:@"Content-Length"];
 
 [theRequest setHTTPMethod:@"POST"];
 
 [theRequest setHTTPBody: [soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
 
 
 
 //initiate the request
 self.sessionconnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
 
 
 if(self.sessionconnection)
 {
 self.webResponseData = [NSMutableData data] ;
 }
 else
 {
 NSLog(@"Connection is NULL");
 }
}

Add these variable to your ViewController

@interface ViewController ()

@property (strong,nonatomic) NSURLConnection *sessionconnection;
@property NSMutableData *webResponseData;

@end

Now, We have to implement the connection delegate methods like below:

//Implement the connection delegate methods.
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
 [self.webResponseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
 [self.webResponseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
 NSLog(@"Some error in your Connection. Please try again.");
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
 
 
 if(connection == self.sessionconnection)
 {
 NSString *theXML = [[NSString alloc] initWithBytes:
 [self.webResponseData mutableBytes] length:[self.webResponseData length] encoding:NSUTF8StringEncoding];
 
 NSLog(@"my data is %@", theXML);
 
 //now parse the xml
 
 }
}

See the output in the console. DONE!!!

Security for Xcode 7.x

The new Xcode 7 requires 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:

  1. Open info.plist file of your project.
  2. 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.

SOAP from iOS

ref link: http://stackoverflow.com/a/32631185/4069848

Parsing the XML

Download and add these two files (XMLReader.h, XMLReader.m) to your projects. And then import the header into your ViewController.

#import "XMLReader.h"

then add below codes to this “connectionDidFinishLoading” delegate function.

NSData *myData = [theXML dataUsingEncoding:NSUTF8StringEncoding];
 
NSError *error = nil;
 
NSDictionary *dict = [XMLReader dictionaryForXMLData:myData
 options:XMLReaderOptionsProcessNamespaces error:&error];
 
NSLog(@"my data is %@", dict);
 
//NSLog(@"my data is %@",[[[[[dict valueForKey:@"Envelope"] valueForKey:@"Body"] valueForKey:@"CelsiusToFahrenheitResponse"]valueForKey:@"CelsiusToFahrenheitResult"]valueForKey:@"text"]);

I hope that helps. Please check some other blogs on web and mobile app development.

3 Comments. Leave new

Very helpful Tutorial, but could you make a vid, or be more specific on where i have to add the code.
Im very new to Swift and am struggling with it.

Reply

Thanks! You saved my day!

Reply

So how the actions are performed? This seems only parsing the xml response, but how the actions in that wsdl response is performed??

Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.