Login | Register   
Twitter
RSS Feed
Download our iPhone app
TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
Browse DevX
Sign up for e-mail newsletters from DevX


advertisement
 

Consuming XML Web Services in iPhone Applications : Page 4

Find out the various ways you can call web services and parse responses from your iPhone applications to give your applications a huge range of data sources.


advertisement

Using HTTP POST with Web Services

To talk to a web service using HTTP POST, you just need to modify the buttonClicked: method, like this:

- (IBAction)buttonClicked:(id)sender { NSString *postString = [NSString stringWithFormat:@"V4IPAddress=%@", ipAddress.text]; NSLog(postString); NSURL *url = [NSURL URLWithString: @"http:// www.ecubicle.net/iptocountry.asmx/FindCountryAsXml"]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; NSString *msgLength = [NSString stringWithFormat:@"%d", [postString length]]; [req addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; [req addValue:msgLength forHTTPHeaderField:@"Content-Length"]; [req setHTTPMethod:@"POST"]; [req setHTTPBody: [postString dataUsingEncoding:NSUTF8StringEncoding]]; [activityIndicator startAnimating]; conn = [[NSURLConnection alloc] initWithRequest:req delegate:self]; if (conn) { webData = [[NSMutableData data] retain]; } }



Basically, you do away with forming the SOAP message and simply post a single string to the web service, such as V4IPAddress=34.5.6.7. When you run the modified application and watch the Debugger Console, you should see a response like this:

<?xml version="1.0" encoding="utf-8"?> <IPCountryService> <Country>United States</Country> </IPCountryService>

Using HTTP GET with Web Services

Using HTTP GET to talk to a web service is even simpler, because you pass all the request information via the query string. The following shows the modified buttonClicked: method to access the web service using the HTTP GET method:

- (IBAction)buttonClicked:(id)sender { NSString *queryString = [NSString stringWithFormat: @"http://www.ecubicle.net/iptocountry.asmx/" + "FindCountryAsXml?V4IPAddress=%@", ipAddress.text]; NSURL *url = [NSURL URLWithString:queryString]; NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:url]; [req addValue:@"text/xml; charset=utf-8" forHTTPHeaderField:@"Content-Type"]; [req addValue:0 forHTTPHeaderField:@"Content-Length"]; [req setHTTPMethod:@"GET"]; [activityIndicator startAnimating]; conn = [[NSURLConnection alloc] initWithRequest:req delegate:self]; if (conn) { webData = [[NSMutableData data] retain]; } }

Like the HTTP POST method, the response in the Debugger Console when you run the modified application should look like this:

<?xml version="1.0" encoding="utf-8"?> <IPCountryService> <Country>United States</Country> </IPCountryService>

Parsing XML Responses

At this point, you're familiar with the various ways to call a web service, now you need to learn how to parse the XML response. The iPhone SDK includes an NSXMLParser object that you can use to parse an XML file. The NSXMLParser class is an implementation of the Simple API for XML (SAX), which parses an XML document (or string) serially.

An NSXMLParser object reads an XML document and scans it from beginning to end. As it encounters the various items in the document (such as elements, attributes, comments, and so on), it notifies its delegates so that you can take appropriate action, such as extracting the value of an element.

To parse the response from the web service, add the following statements to the WebServicesViewController.h file:

#import <UIKit/UIKit.h> @interface WebServicesViewController : UIViewController { //---outlets--- IBOutlet UITextField *ipAddress; IBOutlet UIActivityIndicatorView *activityIndicator; //---web service access--- NSMutableData *webData; NSMutableString *soapResults; NSURLConnection *conn; //---xml parsing--- NSXMLParser *xmlParser; BOOL *elementFound; } @property (nonatomic, retain) UITextField *ipAddress; @property (nonatomic, retain) UIActivityIndicatorView *activityIndicator; - (IBAction)buttonClicked:(id)sender; @end

In the WebServicesViewController.m file, add the statements shown below in bold to the connectionDidFinishLoading: method:

-(void) connectionDidFinishLoading:(NSURLConnection *) connection { NSLog(@"DONE. Received Bytes: %d", [webData length]); NSString *theXML = [[NSString alloc] initWithBytes: [webData mutableBytes] length:[webData length] encoding:NSUTF8StringEncoding]; //---shows the XML--- NSLog(theXML); [theXML release]; [activityIndicator stopAnimating]; if (xmlParser) { [xmlParser release]; } xmlParser = [[NSXMLParser alloc] initWithData: webData]; [xmlParser setDelegate: self]; [xmlParser setShouldResolveExternalEntities:YES]; [xmlParser parse]; [connection release]; [webData release]; }

You create an instance of the NSXMLParser class and then initialize it with the response returned by the web service. As the parser encounters the various items in the XML document, it will fire off several methods, which you need to define next.

The first method to implement is parser:didStartElement:namespaceURI:qualifiedName:attributes:, which is fired when the start tag of an element is found:

//---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:@"Country"]) { if (!soapResults) { soapResults = [[NSMutableString alloc] init]; } elementFound = YES; } }

The preceding code checks to see whether the current tag is <Country>. If it is, you set the Boolean variable elementFound to YES.

The next method to implement is parser:foundCharacters:, which gets fired when the parser finds the text of an element:

-(void)parser:(NSXMLParser *) parser foundCharacters:(NSString *)string { if (elementFound) { [soapResults appendString: string]; } }

Here, if the last tag found was <Country>, you want to extract the value of the Country element into soapResults.

Finally, when the parser encounters the end of an element, it fires the parser:didEndElement:namespaceURI:qualifiedName: method:

//---when the end of element is found--- -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { if ([elementName isEqualToString:@"Country"]) { //---displays the country--- NSLog(soapResults); UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Country found!"

 
Figure 5. Country Found: The completed example application displays the country name after parsing the XML result.

message:soapResults delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil]; [alert show]; [alert release]; [soapResults setString:@""]; elementFound = FALSE; } }

Here, you simply look for the closing </Country> tag; when you find it you know that the value of the Country element has been correctly extracted. You then print out the value using a UIAlertView object.

Finally! You can now test the application on the iPhone Simulator by pressing Command-R. Enter an IP address and click the Find Country button. Figure 5 shows you the result!

At this point, you've seen a working iPhone application that illustrates the various ways you can consume a web service in your iPhone applications: SOAP, HTTP GET, and HTTP POST. The example both calls a web service and shows how to extract data from the XML-formatted response. Using web services (and being able to parse XML) in your iPhone applications can open up an entire world full of data to your applications.



Wei-Meng Lee is a Microsoft MVP and founder of Developer Learning Solutions, a technology company specializing in hands-on training on the latest Microsoft technologies. He is an established developer and trainer specializing in .NET and wireless technologies. Wei-Meng speaks regularly at international conferences and has authored and coauthored numerous books on .NET, XML, and wireless technologies. He writes extensively on topics ranging from .NET to Mac OS X. He is also the author of the .NET Compact Framework Pocket Guide, ASP.NET 2.0: A Developer's Notebook (both from O'Reilly Media, Inc.), and Programming Sudoku (Apress). Here is Wei-Meng's blog.
Comment and Contribute

 

 

 

 

 


(Maximum characters: 1200). You have 1200 characters left.

 

 

Sitemap