Skip navigation

How to consume SOAP web service by passing parameters through Xcode 4.3

16581 Views 16 Replies Latest reply: Feb 22, 2013 12:56 AM by florjon RSS
1 2 Previous Next
munna1116 Calculating status...
Currently Being Moderated
May 18, 2012 2:27 AM

Im new to IOS programming. Can any one guide me "How to consume a simple parametarized dot net web service through Xcode. I have tried all the solutions which I found from the net but all are giving errors or returning NULL value from the web service."

Your help will be highly appreciated.

Thank u.

iPad 2, Mac OS X (10.7)
  • Llessur999 Level 4 Level 4 (1,145 points)

    Xcode itself has no features to automatically generate web service client proxies. You must roll your own client. This give you great flexibility but is a pain.

     

    Some developers stick with Apple's NSURLConnection classes and code all aspects of HTTP request management. Others use 3rd-party libraries so they don't have to write their own code for reachability, authentication, error handling, asynchronous operations, etc.

     

    If you mean SOAP web services, here is an example that consumes a publicly available sample .NET web service to convert temperatures. I used NSURLConnection in this example. Handling REST web services is very similar, but there is no SOAP envelope, and the response data is not necessarily XML.

     

    @interface ViewController : UIViewController {

        NSMutableData *responseData;

    }

     

    @property (weak, nonatomic) IBOutlet UITextField *temperatureTextField;

    @property (weak, nonatomic) IBOutlet UILabel *resultLabel;

     

    - (IBAction)convertButton_TouchUpInside:(id)sender;

     

    @end

    ...

    - (IBAction)convertButton_TouchUpInside:(id)sender {

        // construct envelope (not optimized, intended to show basic steps)

        NSString *envelopeText =

        @"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"

        "<soap12:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema- to instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap12=\"http://www.w3.org/2003/05/soap-envelope\">\n"

        "  <soap12:Body>\n"

        "    <CelsiusToFahrenheit xmlns=\"http://tempuri.org/\">\n"

        "      <Celsius>%@</Celsius>\n"

        "    </CelsiusToFahrenheit>\n"

        "  </soap12:Body>\n"

        "</soap12:Envelope>";

        envelopeText = [NSString stringWithFormat:envelopeText, temperatureTextField.text];

        NSData *envelope = [envelopeText dataUsingEncoding:NSUTF8StringEncoding];

     

        // construct request

        NSString *url = @"http://www.w3schools.com/webservices/tempconvert.asmx";

        NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:url] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:30.0];

        [request setHTTPMethod:@"POST"];

        [request setHTTPBody:envelope];

        [request setValue:@"application/soap+xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];

        [request setValue:[NSString stringWithFormat:@"%d", [envelope length]] forHTTPHeaderField:@"Content-Length"];

     

        // fire away

        NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

        if (connection)

            responseData = [NSMutableData data];

        else

            NSLog(@"NSURLConnection initWithRequest: Failed to return a connection.");

    }

     

    - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

    {

        [responseData setLength:0];

    }

     

    - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data

    {

        [responseData appendData:data];

    }

     

    - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error

    {

        NSLog(@"connection didFailWithError: %@ %@",

              error.localizedDescription,

              [error.userInfo objectForKey:NSURLErrorFailingURLStringErrorKey]);

    }

     

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection

    {

        // extract result using regular expression (only as an example)

        // this is not a good way to do it; should use XPath queries with XML DOM such as GDataXMLDocument

        NSString *responseText = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];

        NSString *pattern = @"<CelsiusToFahrenheitResult>(\\d+\\.?\\d*)</CelsiusToFahrenheitResult>";

        NSError *error = NULL;

        NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:pattern options:NSRegularExpressionCaseInsensitive error:&error];

        NSTextCheckingResult *match = [regex firstMatchInString:responseText options:0 range:NSMakeRange(0, responseText.length)];

        if (match)

            resultLabel.text = [responseText substringWithRange:[match rangeAtIndex:1]];

        else

            resultLabel.text = @"Response error.";

    }

  • Llessur999 Level 4 Level 4 (1,145 points)

    Glad you got it working. If you will be making a lot of differnet SOAP requests, or if the SOAP response has lists of items or multiple values, I recommend using an XML DOM rather than an XML parser. NSXMLDocument is not supported on iOS so you must use a 3rd-party library like Google's GDataXMLDocument.  The following example shows how easy this is to use.

     

    - (void)connectionDidFinishLoading:(NSURLConnection *)connection

    {

        // stuff response into XML doc

        NSError *error = nil;

        GDataXMLDocument *responseXml = [[GDataXMLDocument alloc] initWithData:responseData options:0 error:&error];

        if (error) {

            [NSException raise:@"connectionDidFinishLoading error" format:error.localizedDescription];

        }

       

        // query value

        NSDictionary *namespaces = [NSDictionary dictionaryWithObjectsAndKeys:@"http://tempuri.org/", @"def", @"http://www.w3.org/2003/05/soap-envelope", @"soap", nil];

        NSArray *resultNodes = [responseXml nodesForXPath:@"soap:Envelope/soap:Body/def:CelsiusToFahrenheitResponse/def:CelsiusToFahrenhei tResult" namespaces:namespaces error:&error];

        if (error) {

            [NSException raise:@"connectionDidFinishLoading error" format:error.localizedDescription];

        }

       

        // update user interface

        if (resultNodes.count > 0)

            resultLabel.text = [[resultNodes objectAtIndex:0] stringValue];

        else

            resultLabel.text = @"";

    }

  • Faheem Akhtar Calculating status...

    Hi Mr. Llessur999,

     

    Thnx to you for the above post.

     

    I am using the same code as above for consuming  webservice but if the value returns by one of methods of the webservice is string then I get error but if it is integer then it works fine.

     

    Would you please tell me what to change in the above code to get string value?

     

    Thanx in advance.

     

    Regards

     

    Faheem

  • igg509 Calculating status...

    Hi Munna1116,

     

    Would it be possible to take a look at your source code? I am trying to do the same thing to learn about web services and soap. It would be very helpful. Please let me know if you can do this and I'll send you my email!

     

    Thank you!

  • igg509 Level 1 Level 1 (0 points)

    iglasner@andrew.cmu.edu

     

    Thank you very much for your help!

  • forall02 Calculating status...

    how to send muti parameter  to webservice

  • Llessur999 Level 4 Level 4 (1,145 points)

    If this is a SOAP web service, you include all parameters in the SOAP envelope that you POST as the request.  The envelope format for each operation is described in the service WSDL. Some SOAP endpoints allow GETs with parameters defined in the querystring.

     

    If this is something other than SOAP, for example one of the many REST variants, there is no standard request format so you must consult the documentation for the service. But the same concept applies, parameters are defined in the request body (often JSON) for POST or the querystring for GET.

  • forall02 Level 1 Level 1 (0 points)

    I was in the basic. you have a example or tutorial (send paremater more 1 )

     

    please help me

     

    thank you alot

  • alarshad Calculating status...

    Hi Munna1116,

     

    I am also working with the same kind of SOAP web service. Your code example looks very perfect, but for some reason I am getting and error as

    'NSInvalidArgumentException', reason: '-[__NSCFString setLength:]: unrecognized selector sent to instance 0x68b9b30'.

    In

    -(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response

    {

        [responseData setLength: 0];

    }

     

    Could you kindly help me to look your code. It could be of great help. My email id is alarshad2007@yahoo.com.

     

    Thanks a lot in advance.

  • Llessur999 Level 4 Level 4 (1,145 points)
    NSInvalidArgumentException', reason: '-[__NSCFString setLength:]: unrecognized selector sent to instance 0x68b9b30'.

    Verify that responseData is defined as NSMutableData. Based on the error message, it looks like you incorrectly defined responseData as NSString or NSMutableString.

     

    Could you kindly help me to look your code. It could be of great help.

    The code sample in the second post is complete. Just create a storyboard view with label/text fields corresponding to the two IBOutlets, and a button for the IBAction.

1 2 Previous Next

Actions

More Like This

  • Retrieving data ...

Bookmarked By (0)

Legend

  • This solved my question - 10 points
  • This helped me - 5 points
This site contains user submitted content, comments and opinions and is for informational purposes only. Apple disclaims any and all liability for the acts, omissions and conduct of any third parties in connection with or related to your use of the site. All postings and use of the content on this site are subject to the Apple Support Communities Terms of Use.