The web service which will be consumed is developed in this post.
Our final application should looked like this.
This note is taken from a REST web service which taken its data from a database server.
First, create a new Window Based Application. Use "Notes" as the project name.
Next, create a new UIViewController subclass, check the UITableViewController subclass in the options panel but leave With XIB for user interface unchecked.
Use "NotesTableViewController" as the name.
Create several variables and a method in NotesTableViewController.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@interface NotesTableViewController : UITableViewController { | |
NSMutableString *contentString; | |
NSMutableArray *notes; | |
NSMutableData *xmlData; | |
NSURLConnection *connectionInProgress; | |
} | |
- (void)loadNotes; | |
@end |
Then, we will implement the method in NotesTableViewController.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NotesTableViewController.h" | |
@implementation NotesTableViewController | |
#pragma mark - | |
#pragma mark Initialization | |
- (id)initWithStyle:(UITableViewStyle)style { | |
if (self = [super initWithStyle:style]) { | |
notes = [[NSMutableArray alloc] init]; | |
} | |
// Get the tab bar item | |
UITabBarItem *tbi = [self tabBarItem]; | |
[tbi setTitle:@"Notes List"]; | |
return self; | |
} | |
- (void)loadNotes { | |
[notes removeAllObjects]; | |
[[self tableView] reloadData]; | |
// Construct the web service URL | |
NSURL *url = [NSURL URLWithString:@"http://203.247.166.88:8000/NoteWS/notes"]; | |
NSURLRequest *request = [NSURLRequest requestWithURL:url | |
cachePolicy:NSURLRequestReloadIgnoringCacheData | |
timeoutInterval:30]; | |
// Clear out the existing connection if there is one | |
if (connectionInProgress) { | |
[connectionInProgress cancel]; | |
[connectionInProgress release]; | |
} | |
// Instantiate the object to hold all incoming data | |
[xmlData release]; | |
xmlData = [[NSMutableData alloc] init]; | |
// Create and initiate the connection - non blocking | |
connectionInProgress = [[NSURLConnection alloc] initWithRequest:request | |
delegate:self | |
startImmediately:YES]; | |
} | |
// Kick off the loading whenever NotesTableViewController's table view appears | |
// on the screen by overriding viewWillAppear | |
- (void)viewWillAppear:(BOOL)animated { | |
[super viewWillAppear:animated]; | |
[self loadNotes]; | |
} | |
// This method will be called several times as the data arrives | |
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { | |
[xmlData appendData:data]; | |
} | |
- (void)connectionDidFinishLoading:(NSURLConnection *)connection { | |
// Create the parser object with the data received from the web service | |
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData]; | |
// Give it a delegate | |
[parser setDelegate:self]; | |
// Tell it to start parsing - the document will be parsed and the delegate | |
// of NSXMLParser will get all of its delegate messages sent to it before | |
// this line of execution - it is blocking | |
[parser parse]; | |
// The parser is done (it blocks until done), you can release it immediately | |
[parser release]; | |
[[self tableView] reloadData]; | |
} | |
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { | |
[connectionInProgress release]; | |
connectionInProgress = nil; | |
[xmlData release]; | |
xmlData = nil; | |
NSString *errorString = [NSString stringWithFormat:@"Fetch failed: %@", [error localizedDescription]]; | |
UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:errorString | |
delegate:nil | |
cancelButtonTitle:@"OK" | |
destructiveButtonTitle:nil | |
otherButtonTitles:nil]; | |
[actionSheet showInView:[[self view] window]]; | |
[actionSheet autorelease]; | |
} | |
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName | |
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName | |
attributes:(NSDictionary *)attributeDict { | |
if ([elementName isEqual:@"content"]) { | |
NSLog(@"found content!"); | |
contentString = [[NSMutableString alloc] init]; | |
} | |
} | |
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { | |
[contentString appendString:string]; | |
} | |
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName | |
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { | |
if ([elementName isEqual:@"content"]) { | |
NSLog(@"ended content: %@", contentString); | |
[notes addObject:contentString]; | |
// Release and nil contentString so that the next time characters | |
// are found and not within a content tag, they are ignored | |
[contentString release]; | |
contentString = nil; | |
} | |
} | |
#pragma mark - | |
#pragma mark Table view data source | |
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { | |
// Return the number of rows in the section. | |
return [notes count]; | |
} | |
// Customize the appearance of table view cells. | |
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { | |
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"UITableViewCell"]; | |
if (cell == nil) { | |
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault | |
reuseIdentifier:@"UITableViewCell"] autorelease]; | |
} | |
[[cell textLabel] setText:[notes objectAtIndex:[indexPath row]]]; | |
return cell; | |
} | |
#pragma mark - | |
#pragma mark Memory management | |
- (void)didReceiveMemoryWarning { | |
// Releases the view if it doesn't have a superview. | |
[super didReceiveMemoryWarning]; | |
// Relinquish ownership any cached data, images, etc. that aren't in use. | |
} | |
- (void)dealloc { | |
[super dealloc]; | |
} | |
@end |
Create another UIViewController subclass for handling new note insertion. This time, uncheck the UITableViewController subclass but check the With XIB for user interface. Use "NotesInsertViewController" as the name
Next, create some outlet and a method in our controller. Modify "NotesInsertViewController.h"
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@interface NotesInsertViewController : UIViewController { | |
IBOutlet UITextField *idField; | |
IBOutlet UITextField *contentField; | |
} | |
-(IBAction)insertNote:(id)sender; | |
@end |
Then, double click NotesInsertViewController.xib to open Interface Builder.
Create two UITextField and one Rounded Button.
Connect both UITextField with the appropriate field: idField and contentField
Connect Rounded Button with the insertNote action
Next, implement the method in NotesInsertViewController.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NotesInsertViewController.h" | |
@implementation NotesInsertViewController | |
- (id)init { | |
[super initWithNibName:@"NotesInsertViewController" | |
bundle:nil]; | |
UITabBarItem *tbi = [self tabBarItem]; | |
[tbi setTitle:@"Insert Note"]; | |
return self; | |
} | |
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil { | |
return [self init]; | |
} | |
- (IBAction)insertNote:(id)sender { | |
NSString *post = [NSString stringWithFormat:@"noteId=%@&content=%@&createddate=8", [idField text], [contentField text]]; | |
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES]; | |
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]]; | |
NSMutableURLRequest *request = [[[NSMutableURLRequest alloc] init] autorelease]; | |
[request setURL:[NSURL URLWithString:@"http://203.247.166.88:8000/NoteWS/notes"]]; | |
[request setHTTPMethod:@"POST"]; | |
[request setValue:postLength forHTTPHeaderField:@"Content-Length"]; | |
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; | |
[request setHTTPBody:postData]; | |
NSURLConnection *conn=[[NSURLConnection alloc] initWithRequest:request delegate:self]; | |
if (conn) | |
{ | |
} | |
else | |
{ | |
} | |
} | |
- (void)didReceiveMemoryWarning { | |
// Releases the view if it doesn't have a superview. | |
[super didReceiveMemoryWarning]; | |
// Release any cached data, images, etc. that aren't in use. | |
} | |
- (void)viewDidUnload { | |
[super viewDidUnload]; | |
// Release any retained subviews of the main view. | |
// e.g. self.myOutlet = nil; | |
} | |
- (void)dealloc { | |
[super dealloc]; | |
} | |
@end |
After this we can create the tab controller to navigate between the view table and insert view
Open and edit NotesAppDelegate.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import <UIKit/UIKit.h> | |
@interface NotesAppDelegate : NSObject <UIApplicationDelegate> { | |
UIWindow *window; | |
UITabBarController *tabBarController; | |
} | |
@property (nonatomic, retain) IBOutlet UIWindow *window; | |
@end |
Create a UITabBarController and assign each tab item with the appropriate controller. Open and edit NotesAppDelegate.m
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#import "NotesAppDelegate.h" | |
#import "NotesTableViewController.h" | |
#import "NotesInsertViewController.h" | |
@implementation NotesAppDelegate | |
@synthesize window; | |
#pragma mark - | |
#pragma mark Application lifecycle | |
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { | |
// Create the tabBarController | |
tabBarController = [[UITabBarController alloc] init]; | |
// Create two view controllers | |
UIViewController *notesTable = [[NotesTableViewController alloc] initWithStyle:UITableViewStylePlain]; | |
UIViewController *notesInsert = [[NotesInsertViewController alloc] init]; | |
// Make an array containing the two view controllers | |
NSArray *viewControllers = [NSArray arrayWithObjects:notesInsert, notesTable, nil]; | |
[notesTable release]; | |
[notesInsert release]; | |
// Attach them to the tab bar controller | |
[tabBarController setViewControllers:viewControllers]; | |
// Put the tabBarController's view on the window | |
[window addSubview:[tabBarController view]]; | |
[self.window makeKeyAndVisible]; | |
return YES; | |
} | |
- (void)dealloc { | |
[window release]; | |
[super dealloc]; | |
} | |
@end |
Build & run our application.
Notice that in inserting a new note we hardcode the date as a string and put 8 which will be interpreted by the web service as "8 seconds after 1 January 1970"
It is a little buggy and the view might not as good. But the point of the tutorial is on consuming REST Web Service, so i decide to make a minimum design and focus on the methods for handling Web Service.
Anyways, enjoy playing with REST Web Service!
Nice Article Tom i loved it..... :)
ReplyDeleteHi,Not everyone is a good designer. Planning websites in Web Design Cochin is a taste for many individuals and myself.Thanks.........
ReplyDeleteGreat Article
ReplyDeleteJava Web Services Online Training
Web Services Course
Web Services Training Courses
Java Web Services Training in Chennai