1 2 Previous Next 16 Replies Latest reply: Feb 22, 2013 12:56 AM by florjon
munna1116 Level 1 Level 1 (0 points)

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)
  • 1. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    Llessur999 Level 4 Level 4 (1,170 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.";

    }

  • 2. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    munna1116 Level 1 Level 1 (0 points)

    Mr. Llessur999, Thank u so much for your reply. Let me check on this and get back to u with result.

  • 3. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    munna1116 Level 1 Level 1 (0 points)

    The code which you gave, helped me alot. But by doing some small changed i got the result.

    Here is the Code for consuming a sample Webservice .......Its working great to me....

     

    - (IBAction)convertButton:(id)sender {

       

       

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

        NSString *envelopeText =[NSString stringWithFormat:@"<?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>",temperatureTextField.text];

       

        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 addValue:@"http://tempuri.org/CelsiusToFahrenheit" forHTTPHeaderField:@"SOAPAction"];

     

       

        [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 {

         

        NSLog(@"DONE. Received Bytes:%d",[responseData length]);

            

             NSString *theXml = [[NSString alloc] initWithBytes:[responseData mutableBytes] length:[responseData length] encoding:NSUTF8StringEncoding];

            

             NSLog(@"The final result :%@",theXml);

     

    if(xmlParser)

    {

     

    }

        xmlParser = [[NSXMLParser alloc] initWithData: responseData];

        [xmlParser setDelegate:self];

        [xmlParser setShouldResolveExternalEntities:YES];

        [xmlParser parse];

    }

     

    //---when the start of an element is found---

    -(void) parser:(NSXMLParser *) parser didStartElement:(NSString *) elementName namespaceURI:(NSString *) namespaceURI qualifiedName:(NSString *) qName attributes:(NSDictionary *)attributeDict {

        if( [elementName isEqualToString:@"CelsiusToFahrenheitResult"])

        {

            if (!soapResults)

            {

                soapResults = [[NSMutableString alloc] init];

            }

            elementFound = YES;

        }

    }

     

     

    -(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string

    {

        if (elementFound)

        {

            [soapResults appendString: string];

        }

    }

     

    //---when the end of element is found---

    -(void)parser:(NSXMLParser *)parser

    didEndElement:(NSString *)elementName

    namespaceURI:(NSString *)namespaceURI

    qualifiedName:(NSString *)qName

    {

        if ([elementName isEqualToString:@"CelsiusToFahrenheitResult"])

        {

            //---displays the country---

            NSLog(@"%@",soapResults);

            UIAlertView *alert = [[UIAlertView alloc]

                                  initWithTitle:@"Fahrenheit Value!"

                                  message:soapResults

                                  delegate:self

                                  cancelButtonTitle:@"OK"

                                  otherButtonTitles:nil];

            [alert show];

            resultLabel.text=soapResults;

            //[alert release];

            [soapResults setString:@""];

            elementFound = FALSE;

        }

    }

  • 4. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    Llessur999 Level 4 Level 4 (1,170 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 = @"";

    }

  • 5. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    munna1116 Level 1 Level 1 (0 points)

    As of now i am returning only single value, so i have used XML parsing, may be in future may be returning multiple values will come that time i am sure it will be very helpfull for me.

    Thank you so much.

    Mr. Llessur999 i have one problem regarding tracking the current location when the app is running (with the intervals of every 10 mins.). I have posted my problem in the discussion but till now i did not get any proper response about it. Please help me.

    Thank u.

     

  • 6. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    Faheem Akhtar Level 1 Level 1 (0 points)

    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

  • 7. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    igg509 Level 1 Level 1 (0 points)

    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!

  • 8. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    munna1116 Level 1 Level 1 (0 points)

    Okey dear no problem.

    If you want i can mail you the source code files to ur email. Send me ur mail.

  • 9. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    igg509 Level 1 Level 1 (0 points)

    iglasner@andrew.cmu.edu

     

    Thank you very much for your help!

  • 10. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    forall02 Level 1 Level 1 (0 points)

    how to send muti parameter  to webservice

  • 11. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    Llessur999 Level 4 Level 4 (1,170 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.

  • 12. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    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

  • 13. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    alarshad Level 1 Level 1 (0 points)

    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.

  • 14. Re: How to consume SOAP web service by passing parameters through Xcode 4.3
    Llessur999 Level 4 Level 4 (1,170 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