Saturday, December 25, 2010

Handling SOAP with iPhone

Hi All,

I am writing this blog to help you all in Parsing XML(SOAP) response.
In coming sections I'm gonna give you basic steps to parse XMLResponse and later with some extremely useful links to make your work a piece of cake when it comes to handling SOAP in iPhone.

Basic Steps (This are the steps needs to be done while sending request and parsing XMLResponse) :


//Sending Request

NSURL *url = [NSURL URLWithString:@"https://servername.com/WebService/WebServicename.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d",[soapMessage length]];
[theRequest addValue:@"text/xml" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue:@"servername.com/Hello" forHTTPHeaderField:@"SOAPAction"];
[theRequest addValue:msgLength forHTTPHeaderField:@"Content-Length"];
[theRequest setHTTPMethod:@"POST"];
[theRequest setHTTPBody:[soapMessage dataUsingEncoding:NSUTF8StringEncoding]];
NSURLConnection *theConnection = [[NSURLConnection alloc] initWithRequest:theRequest delegate:self];
if(theConnection)
webData = [[NSMutableData data] retain];
//here webdata is => NSMutableArray *webdata; 
else 
NSLog(@"theConnection is null");
//At this point connection is setup and delegate is set to self, now is time to use connection delegate methods. Four methods that we gonna use:

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
[webData setLength:0];
}

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

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
NSLog(@"Error with connection %@",error);
[connection release];
[webData release];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"Done. received Bytes %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes:[webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
[theXML release];
//xmlparser declared in header as => NSXMLParser *xmlparser

if(xmlParser)
{
[xmlParser release];
}
xmlParser = [[NSXMLParser alloc] initWithData:webData];
[xmlParser setDelegate:self];
[xmlParser setShouldResolveExternalEntities:YES];
[xmlParser parse];
 
[connection release];
[webData release];
}


  • //Now we will start of XMLParsing as we have response needed.

This method is to check start of elements. 
If element is equal to "Result", set BOOL (recordResults) to true, and initialize the MutableString (soapResults):
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
if([elementName isEqualToString:@"Result"])
{
if(!token)
{
soapResults = [[NSMutableString alloc] init];
}
recordResults = TRUE;
}
}

//This method is to store the result between element (Result):
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{

if(recordResults)
{
[soapResults appendString:string];
}

//NSLog(@" soap: %@", soapResults);
}

//This third method where we will look for end element (Result in our case), here you may/can do some changes and format your result you want it to handle.

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName 
{
if([elementName isEqualToString:@"Result"])

{
if(!token)
{
token = [[NSString alloc] initWithString:soapResults];
NSLog(@"auth1 token: %@",token);
}
        //Do Something with result here

recordResults = FALSE;
[soapResults release];
soapResults = nil;
}
}



I have given you basics of XML request and parsing so far, from this point if your programming skill are good can manage to handle any response.

But for those and also in real application mostly XMLResponse are not that easy to read and analyze to our needs. To do that I have come through some useful links and work done by others to make our job easier, I am posting those links with some information about them, you can choose link of your choice.
  • Sudzc
It has all, just give your web service link to the site, they will generate request and response handler for all web services method on that address and a simple tutorial to explain how to use it. 
Straightforward work, excellent for newbies and who dun want to waste their time writing code.


  • wsdl2objc

Its another approach,  not recommended ny me and many others.

  • In case response you getting is like:<Menus>
    <Table1>
    <Restaurant_Name>CHICK-FIL-A</Restaurant_Name>
    <Restaurant_id>2748</Restaurant_id>
    <billing_city>DECATUR</billing_city>
    <billing_state>GA</billing_state>
    </Table1>
    </Menus>

    I have done some work to handle this response according to my need, if needed can ask me will provide help in handling this response.
Please feel free to ask and comment your view.

Thanks
AB

23 comments:

  1. Awesome..! It really worked out for me :) Can you post the sample for response that you have mentioned in last


    CHICK-FIL-A
    2748
    DECATUR
    GA


    That will exactly help me out :) Thanks in Advance !

    ReplyDelete
  2. You want to handle similar response?

    ReplyDelete
  3. Yes It will do.. by the way do you know how to populate soap response in UITableView ??

    ReplyDelete
  4. This comment has been removed by the author.

    ReplyDelete
  5. I have written XMLreader class which read XML response and convert it not dictionary (Like jSON resposne), as JSON is easy to handle and use in iphone. I can't post whole code of that class here, give me your mail id i'l send u class with how to use it code.

    For populating soap response in table once you have response handeld properly and stored in NSArray or some other you can use it to populate tableview. I used singleton class approach (sharing values in different classes) which i use to store soap response and access it in tableview or any other.

    ReplyDelete
    Replies
    1. Hi Abhinav

      I'm stuck with this

      Can you send me code

      Maduka

      Delete
    2. Hi Abhinav, can you please send me the code (rosa_cristian_jr@yahoo.com). Thank you!

      Delete
  6. Hey, great post. Right now I'm using sudzc but my results aren't parsing correctly. It doesn't parse into XML, all I have is a giant object with the results in HTML.

    Any ideas how to parse this information correctly? I'm thinking about just changing out sudzc and using the code you have above. Any help appreciated. Thanks.

    ReplyDelete
  7. Hey Brad,
    XML Parsing is not an easy task with NSXMLParser. You can always use the above code to parse XML, if XML is not as simple and have multiple nested elements you have to modify didStartElement method and so on according to XML and your need.
    I can try to help you if you can explain your exact problem.

    ReplyDelete
  8. "if XML is not as simple and have multiple nested elements you have to modify didStartElement method and so on according to XML and your need."

    Can you explain it with a sample please?

    ReplyDelete
  9. How do I sereialize the webservice data as an object?

    ReplyDelete
  10. This comment has been removed by the author.

    ReplyDelete
  11. I am using The above code to call Wcf Webservice
    But It is having .SVC instead of .asmx.. and it is returning 0 bytes..What should I do

    ReplyDelete
    Replies
    1. http://www.xcode-tutorials.com/parsing-xml-files/

      Delete
  12. Try WSClient++ http://wsclient.neurospeech.com

    ReplyDelete
  13. Hey how do u handle multiple soap responses and parse them?

    Katy

    ReplyDelete
  14. Thnx for the tutorial, how can i handle this response ?



    product 1
    p1
    1


    pruduct2
    p2
    2

    .
    .
    .

    ReplyDelete
  15. for more detail ,


    http://www.xcode-tutorials.com/parsing-xml-files/

    ReplyDelete
  16. http://code.google.com/p/wsdl2objc/
    works a treat

    ReplyDelete
  17. Please send me code on rathod3171@gmail.com

    ReplyDelete
  18. please send me the complete code of your tutorial, because i m new on webservices used in iphone(naveedurrehman34@gmail.com), And other thing how to handle php soap services in iphone. beacuse over php developer used Soap webservices and than through obj C code we will get response, but how?

    ReplyDelete
  19. kindly send me the code to pdipes77@gmail.com..It would be a great help

    ReplyDelete
  20. In case response you getting is like:

    CHICK-FIL-A
    2748
    DECATUR
    GA




    i need parse like this data in ios ....please help me

    ReplyDelete