On my work, technology and related stuff....

Posts Tagged ‘wsdl2objc’

32 comments

This post describes how to invoke a SOAP based web service from your iOS app. The post is not going to dwell into the discussion of SOAP based versus a RESTful service and neither is it intended to be a tutorial on SOAP. For more information on the latter,there are plenty of online resources including the W3C (http://www.w3.org/TR/soap/). This post assumes that your needs require invocation of SOAP based web services from your iOS app.

We will use a free online web service http://www.webservicex.net/CurrencyConvertor.asmx?WSDL for our example. This is a very simple web service handles currency conversions (surprise!).

I recommend a free utility called "wsdl2objc" which generates client-side Objective-C code from a SOAP Web Services Definition File (WSDL) file. You can always construct the SOAP request messages and parse the SOAP responses on your own without the tool, however, the tool does a lot of the heavy lifting and is convenient.

1. Download the wsdl2objc tool from http://code.google.com/p/wsdl2objc/

2. Run the wsdl2objc tool . Enter the source URL for the WSDL and the destination folder for the generated ObjC files and select "Parse WSDL" button. A screenshot of the same is shown below

3. Once the "Parse WSDL" process completes, you should see a number of ObjC files in the destination folder.

4. Follow the following steps to integrate the ObjC files into your app.
4a) Copy the ObjC files that were generated in the previous step to your app project. Make sure you select the "Copy Files Into Destination Folder" option.
Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-copyfiles.png

4b) If you are using ARC in your project, you will have to disable ARC for the generated ObjC files. To do this, go to the "Compile Sources" section of "Build Phases" of your project and specify the "-fno-objc-arc" compiler flag for all the generated files.
Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-disableARC.png

4c) If you already have libxml2 installed on your system (look for libxml2.dylib in /usr/lib folder), then skip this step. Otherwise, follow the steps in (4c) to install libxml2 library
4c-1)  Install the macports package installer from http://www.macports.org/install.php (if you don't have it already)
4c-2) Install libxml2 library by executing the following command in a terminal window
        sudo port install libxml2

(*Tip* For the build to work for libxml2, make sure you have the command line tools installed for Xcode )

4d) In the target "Build settings", include "-lxml2" in the "Other Linker Flags"  property
Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-linkerflags.png

4e) In the target "Build settings", include "$(SDKROOT)/usr/include/libxml2" in the "Header Search Paths"  property

Description: Macintosh HD 2 Mountain Lion:Users:mactester:Downloads:post:screenshot-headerfiles.png

4f) Import "CurrencyConvertorSvc.h" file into your implementation file and use the methods provided by this interface to make the appropriate web services calls.

The following code snippet demonstrate its usage

-(void)processRequest

{

    CurrencyConvertorSoapBinding* binding = [CurrencyConvertorSvcCurrencyConvertorSoapBinding];

    CurrencyConvertorSoapBindingResponse* response;

    CurrencyConvertorSvc_ConversionRate* request = [[CurrencyConvertorSvc_ConversionRatealloc]init];

    request.FromCurrencyCurrencyConvertorSvc_Currency_enumFromString(self.fromCurrencyTextField.text);

    request.ToCurrency = CurrencyConvertorSvc_Currency_enumFromString(self.toCurrencyTextField.text );

    response = [binding ConversionRateUsingParameters:request];

 

    dispatch_async(dispatch_get_main_queue(), ^{

        [self processResponse:response];

    });

}

 

 

-(void) processResponse: (CurrencyConvertorSoapBindingResponse*)soapResponse

{

    NSArray *responseBodyParts = soapResponse.bodyParts;

    id bodyPart;

    [self.activitystopAnimating];

    [self.activityremoveFromSuperview];

    @try{

        bodyPart = [responseBodyParts objectAtIndex:0]; // Assuming just 1 part in response which is fine

 

    }

    @catch (NSException* exception)

    {

        UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"Server Error"message:@"Error while trying to process request"delegate:selfcancelButtonTitle:@"OK"otherButtonTitles: nil];

        [alert show];

        return;

    }

 

    if ([bodyPart isKindOfClass:[SOAPFault class]]) {

 

        NSString* errorMesg = ((SOAPFault *)bodyPart).simpleFaultString;

        UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"Server Error"message:errorMesg delegate:selfcancelButtonTitle:@"OK"otherButtonTitles: nil];

        [alert show];

    }

    elseif([bodyPart isKindOfClass:[CurrencyConvertorSvc_ConversionRateResponseclass]]) {

        CurrencyConvertorSvc_ConversionRateResponse* rateResponse = bodyPart;

        UIAlertView* alert = [[UIAlertViewalloc]initWithTitle:@"Success!"message:[NSStringstringWithFormat:@"Currency Conversion Rate is %@",rateResponse.ConversionRateResult] delegate:selfcancelButtonTitle:@"OK"otherButtonTitles: nil];

        [alert show];

 

    }

 

}

 

An example project can be downloaded from the following link-  SOAP Test. The project has been built using Xcode 4.5.