DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones AWS Cloud
by AWS Developer Relations
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Partner Zones
AWS Cloud
by AWS Developer Relations

Creating and Using Your Own Delegates in Objective-C

Gregg Bolinger user avatar by
Gregg Bolinger
·
Feb. 04, 10 · Interview
Like (0)
Save
Tweet
Share
71.15K Views

Join the DZone community and get the full member experience.

Join For Free
I've been doing iPhone development for about a year now and have used the delegation pattern many times. Specifically with regards to UITableViews and object serialization (NSCoding, NSCopying). Wikipedia has a great write up on the delegation pattern as well as examples in a few languages like Java, C++ and even Objective-C. The problem is that these examples, for me, don't express how powerful and how easy they are to implement and use.

Recently, I've been working on a project where I needed to access a series of web services to post and get my data. This is a pretty common thing to do however, if you look at the many examples of how to do this you'll find overly simplistic code that throws everything into a single class/file and completely ignored code reuse or good Object Oriented design.

The Scenario
My scenario was this; I needed to be able to access several web services from several different form/classes in the application. I not only wanted the class to send the data to the web service, but also retrieve it and do something with the data it got back, which in my case was a SOAP response.

The Problem
Calling a SOAP web service with the iPhone relies on using the NSURLConnection which sends an asynchronous call to the server. It relies on it's own delegate to deal with each process of the call.  My initial web service impementation looked like this:

#import "UserWebService.h"

@implementation UserWebService

@synthesize users;

-(id)initWithUserData: (User *)user {
// code here to initialize the request with user data
}

-(void) send {
NSURLConnection *theConnection = [[NSURLConnection alloc]initWithRequest:theRequest delegate:self];
[theConnection release];
}

-(void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
NSLog(@"Received Response");
[webData setLength:0];
}

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
NSLog(@"Got Data");
[webData appendData:data];
}

-(void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
[webData release];
[connection release];
}

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

// code here to do something with all the data (XML) that was returned

}

 And then to use this I have the following code in another class, a UIViewController subclass where I needed the data

User *user = [[User alloc]init];
[user setUserId:@"userid"];
[user setPassword:@"password"];

ws = [[UserWebService alloc ]initWithUserData:user];
[user release];
[ws send];

NSArray *users = [ws users];

 But here's the problem.  When we call [ws users] to get the array of users back from the web service there is no way to know if that web service has completed yet.  I kept getting zero users back even though I knew, by stepping through my code, it was getting 3 users back.

The Solution

 I needed to find a way to notify my UIViewController subclass that the web service had completed.  This is where our custom delegate comes to play.  First, you define a protocol for your delegate in a header file:

@protocol WsCompleteDelegate
-(void) finished;
@end

 Next, we modify our web service to notify the delegate when it has completed.  In the web service class header file we define a delegate property like so:

@interface UserWebService : NSObject {

id <WsCompleteDelegate> delegate;

}

@property (retain, nonatomic) id <WsCompleteDelegate> delegate;

@end

 Then in our web service class' connectionDidFinishLoading method, we simply call our delegate method:

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {

// do all necessary wrap up work
[delegate finished];

}

 The next step is to use this delegate in our UIViewController subclass.  First, we modify the header file like so:

@interface LoginViewController : UIViewController <WsCompleteDelegate> {
// other code here
}

 Then in the implementation file we have to do two things. First, we tell the web service instance what it's delegate is, which is the LoginViewController, or in Objective-C, 'self' and then  we impement the delegate's 'finish' method.

-(IBAction)submit {	
User *user = [[User alloc]init];
[user setUserId:@"username"];
[user setPassword:@"password"];

ws = [[UserWebService alloc ]initWithUserData:user];

ws.delegate = self;

[user release];
[ws send];
}

-(void) finished {
NSArray *users = [ws users];
}

 When the web service class calls [delegate finished] it notifies all classes listening to that delegate and the 'finished' method is called. We now know the web service has completed and can safely get the array of users from it.  Then we just do whatever we need to do with them.

Conclusion

There are lots of possibilites for the delegation pattern and this is just one of them.  But it proved to be very simple to implement and an elegant solution to a possibly combersome problem.

 

Web Service Objective C

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • 5 Best Python Testing Frameworks
  • 19 Most Common OpenSSL Commands for 2023
  • Chaos Engineering Tutorial: Comprehensive Guide With Best Practices
  • How To Select Multiple Checkboxes in Selenium WebDriver Using Java

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: