How to call Soap Webservices SynchronouslyPosted by simon on May 10th, 2009
As I browsed the internet I found a few examples of how to call soap webservices on the iphone. The main example I found actually generated 3 calls – 2 asynchronous and 1 synchronous calls. I then decided a much more concise static method was needed to do the job and while the example I had found works, it isn’t something you would ever want to use in your own application. With that said, here is my solution.
Also to note, If you create a NSURLConnection and don’t use the static sendSynchronousRequest method, you are creating an asynchronous call and should be aware of that.
+ (NSString *)sendSOAPRequest:(NSString *) sRequest
NSURL *) wsURL
NSString *) sHeader
{
NSMutableData *myMutableData = [[NSMutableData data] retain];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:wsURL];
[request addValue:@"text/xml; charset:UTF-8" forHTTPHeaderField:@"Content-Type"];
[request addValue:sHeader forHTTPHeaderField:@"SOAPAction"];
NSString *contentLengthStr = [[NSString alloc] initWithFormat:@”%d”, [sRequest length]];
[request addValue:contentLengthStr forHTTPHeaderField:@"Content-Length"];
[request setHTTPMethod:@"POST"];
[request setHTTPBody:[sRequest dataUsingEncoding:NSUTF8StringEncoding]];
NSError *WSerror;
NSURLResponse *WSresponse;
@try
{
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
myMutableData = (NSMutableData *)[NSURLConnection sendSynchronousRequest:request
returningResponse:&WSresponse error:&WSerror];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}
@catch( NSException* ex )
{
NSLog(@”Webservice Request Failed: Error %@”, [WSerror code]);
}
NSString *theXml = [[NSString alloc]initWithBytes:[myMutableData mutableBytes] length:[myMutableData length] encoding:NSUTF8StringEncoding];
[request release];
[contentLengthStr release];
return [theXml autorelease];
}
Here is a sample Call
+(NSString *) getAuthTokenAndLogin
NSString *) nsUsername
NSString *) nsPassword
{
NSString* nsAuthToken = [[NSString alloc] initWithString:@”"];
NSMutableString *sRequest = [[NSMutableString alloc] init];
[sRequest appendString:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>"];
[sRequest appendString:@"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"];
[sRequest appendString:@"<soap:Body>"];
[sRequest appendString:@"<GetToken xmlns=\"#Service\">"];
[sRequest appendString:@"<RequestXml>"];
[sRequest appendString:@"<Credentials Username=\""];
[sRequest appendString:nsUsername];
[sRequest appendString:@"\" Password=\""];
[sRequest appendString:nsPassword];
[sRequest appendString:@"\" />"];
[sRequest appendString:@"</RequestXml>"];
[sRequest appendString:@"</GetToken>"];
[sRequest appendString:@"</soap:Body>"];
[sRequest appendString:@"</soap:Envelope>"];
NSURL* wsURL = [NSURL URLWithString:@"https://virtualroot.com/service.asmx?op=GetToken"];
NSString* responseData = [WebServices sendSOAPRequest: sRequest: wsURL :@"#ServiceAggregator/GetToken"];
NSString* responseXML = [self getElementValue :responseData :@"ResponseXml>" :@"</ResponseXml" ];
HTMLDecoder*htmldecode = [[HTMLDecoder alloc] init];
NSString* xmlData = [htmldecode convertEntiesInString:responseXML];
NSString* nsToken = [self getElementValue
mlData :@"Token>" :@"</Token" ];
nsAuthToken = nsToken;
[sRequest release];
return [nsAuthToken autorelease];
}
Hopefully you can make this work for your own webservice, This call will actually fail since the URL doesn’t resolve to anything but this code is from some code I have written previously. I’ll be posting further examples of how I Decode XML using NSXMLParser and how I get substrings as there were topics that were not well documented on the interwebs.
June 17th, 2009 at 5:36 am
Hi simon,
Thanks for posting this….its great.
can you please post the getElementValue also…
June 17th, 2009 at 9:46 am
I already have. Please check out. NSString – Getting a Substring
June 18th, 2009 at 7:06 am
Thanks. It helped me a lot.
But when I use similar code for Saving information to Database, only blank rows get inserted in the table instead of my input. Is there anything specific I need to do with the web service for accessing this data?
June 20th, 2009 at 3:33 pm
There shouldn’t be anything special you need to do, you might want to verify your inputs. Use some NSLog calls to see where that data is getting lost.
July 2nd, 2009 at 3:36 am
hi Simon,
Thanks for the reply. I had a typo error in SOAP request. I have one more request. How to parse XML file into an Array; got many samples on web, but all are specific to a particular XML file. How to write a generalized(common) XML Parser to parse XML files of different type and format? For example, i have a table view and picker view in my App, have to fill both with different sets of data from my remote DB. Can i write a common file/class to parse the XML received? if so, how to write? Please help me. Struggling for more than 2 days..:(
Thanks in advance.