Introduction
As you know, web services are widely used to make applications to communicate each other. In this article, I will show how to call an
ASMX service in iOS. Simply, we will send a Celsius value to the server and the server will convert it to Fahrenheit.
Background
It is assumed that the reader already has knowledge about Objective C, Xcode, and general Webservice structure.
Using the code
What is WebService?
Simply, a webservice is a method that allows devices to communicate with each other.
How is this happening?
Very simply, there are some methods on the server side and the client reaches those methods by sending a request. This request may contain some parameters for the methods. After the server performs the action, it returns the answer. But how? SOAP objects...
SOAP Object?
SOPA is a protocol which allows to share information with a certain format. Actually it is a type of XML.
Now we can start our application. Here are the steps:
- Download ASIHTTPRequest framework
- Download JSON framework
- Add other needed frameworks
- Coding
1- Download ASIHTTPRequest
Go to the following link and get your framework; after downloading, copy all the files under the "classes" folder to your project framework folder.
2- Download JSON framework
Go to the following link and get your framework; after downloading, copy all the files under the
src/main/obj folder to your project framework folder.
3- Add other needed frameworks
From Project Explorer select your project and go to the Build Phases tab, then click Link Binary With Libraries, click + sign, and find the following frameworks and add them. You will see that, they will be added to your project but it is better to move them to your project framework folder:
- CFNetwork.framework SystemConfiguration.frameworkMobileCoreServices.framework libz.1.2.3.dylib
3- Coding
Create an interface like this :
Import the frameworks header to your ViewController header file :
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
#import "SBJson.h"
Unfortunately, there is no framework to create a SOAP message for us, so we will create the SOAP message as follows (this is the routine) :
- (IBAction)btnConvert:(id)sender {
NSString *soapMessage = [NSString stringWithFormat:@"<?xml version=\"1.0\" encoding=\"utf-8\"?>\n"
"<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/\">\n"
"<soap:Body>\n"
" <CelsiusToFahrenheit xmlns=\"http://tempuri.org/\">\n"
"<Celsius>%@</Celsius>\n"
"</CelsiusToFahrenheit>\n"
"</soap:Body>\n"
"</soap:Envelope>\n" ,textFieldCelcisus.text];
NSURL *url = [NSURL URLWithString:@"http://w3schools.com/webservices/tempconvert.asmx"];
NSMutableURLRequest *theRequest = [NSMutableURLRequest requestWithURL:url];
NSString *msgLength = [NSString stringWithFormat:@"%d", [soapMessage length]];
[theRequest addValue: @"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[theRequest addValue: @"http://tempuri.org/CelsiusToFahrenheit" 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] ;
NSLog(@"Problem");
}
else
{
NSLog(@"theConnection is NULL");
}
}
After making our request to the server, we need to catch the server response, for this.
By using the connectionDidFinishLoading
method, we catch the service response.
-(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 theConenction");
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes:
[webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
}
Now we got the data in XML form, but we need to parse this XML to get our fahrenheit value. To do that, we need to add NSXMLParser
's delegate to our viewController:
@interface SEViewController : UIViewController <NSXMLParserDelegate>
In connectionDidFinishLoading
method, we create an NSXMLParser
object and pass the server response to it:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
NSLog(@"DONE. Received Bytes: %d", [webData length]);
NSString *theXML = [[NSString alloc] initWithBytes:
[webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding];
NSData *myData = [theXML dataUsingEncoding:NSUTF8StringEncoding];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:myData];
xmlParser.delegate = self;
BOOL parsingResult = [xmlParser parse];
}
Finally, we will implement NSXMLParser
's delegate methods to get each element:
-(void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSString *currentDescription = [NSString alloc];
}
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
curDescription = string;
}
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
if([elementName isEqual: @"CelsiusToFahrenheitResult"]);
textFieldResult.text = curDescription;
}