Exchanging data using Delegates in iOS

Introduction

The delegates are quite a powerful concept when it comes to exchanging data in iOs or query some other class without knowing much about it. This post will cover the process to create a simple delegate and how to make it work to exchange data between different view controllers.

Delegation Pattern:

As per wikipedia, The delegation pattern is a design pattern in object-oriented programming where an object, instead of performing one of its stated tasks, delegates that task to an associated helper object.

Somehow it also allows us to implement the concept of Multiple Inheritance in iOS by allowing helper class to perform operations on behalf of the base class.

Summary

The post consists of an example which consists of the following files:

CMGViewController: Base Controller which come to the view when the user loads the application. It implements the CMGViewControllerDelegate to perform an operation on behalf of CMGSecondViewController.

CMGSecondViewController: This is a view controller which asks for the user input. Once the user input the data to control and submits it, the data is displayed on the control is send back to the CMGViewController along with the input added by the user.

Download the full source of the example from here: DOWNLOAD SOURCE

Lets begin with the more interesting stuff and understand how the delegation pattern works.

Code

Step 1: Open Xcode and create a new project with Single View Application selected.

Step 2: Add a view controller to the application.

Step 3: Open the .h file for the controller


@protocol CMGSecondViewControllerDelegate <NSObject>

-(void) submitButtonActionPerformed:(NSString *) stringValue;

@end

#import <UIKit/UIKit.h>

@interface CMGSecondViewController : UIViewController
@property (strong,nonatomic) id<CMGSecondViewControllerDelegate> delegate;
@property (strong,nonatomic) IBOutlet UITextField *departmentTextField;
@property (strong,nonatomic) IBOutlet UIButton *submitButton;

-(IBAction)submitButtonPressed:(id)sender;

What we have here?

We have created a new protocol for the application with the specified name which our main view controller will implement to perform operations on behalf of our second view controller. We have declared a method here which returns nothing but takes a NSString as an argument.


@protocol CMGSecondViewControllerDelegate <NSObject>

-(void) submitButtonActionPerformed:(NSString *) stringValue;

@end

We have an instance of UITextField and UIButton which allows user to interact with the application. The user types in the data to the textfield and submits it. The data is accordingly displayed on instance of UILabel in main view controller.

Now we have to declare a property here with the type as the delegate name.


@property (strong,nonatomic) id<CMGSecondViewControllerDelegate> delegate;

Remember you have to connect your controls to the Storyboard View. I leave the connection stuff to you as I pre assume that you will be able to do that easily.

Step 4: Switch to your .m file for the controller and add the following code to it.


@synthesize departmentTextField;
@synthesize submitButton;

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

// Submit Button Action Performed
-(void) submitButtonPressed:(id)sender
{
NSString *textFieldValue = [self.departmentTextField text];
[self dismissViewControllerAnimated:YES completion:^{
[self.delegate submitButtonActionPerformed:textFieldValue];
}];
}

Above code consists of an action method that is performed when the user hits the button on the controller view. It dismisses the current dialog and passes the value to the first view controller to display in the label instance. We have to make a call to submitButtonActionPerformed: method on the delegate instance to call the implementation in the main controller file. This code is added in the completion block of the dismissViewControllerAnimated: method.

Step 5: Now switch to your main controller .h file and add the following code for your delegate pattern to work correctly.


#import "CMGSecondViewController.h"

@interface CMGViewController : UIViewController <CMGSecondViewControllerDelegate>

@property (strong,nonatomic) IBOutlet UILabel *departmentLabel;

Here we add the protocol that we defined in the second view controller file in between the angle brackets so that we can access the methods and provide an implementation of it in the .m file.

Step 6: Add the following code to .m file. This consists of  implementation of protocol methods as we generally do in iOS.


//
//  CMGViewController.m
//  DelegateExample
//
//  Created by CMGabriel on 03/12/13.
//  Copyright (c) 2013 Example. All rights reserved.
//

#import "CMGViewController.h"
#import "CMGSecondViewController.h"

@interface CMGViewController ()

@end

@implementation CMGViewController

@synthesize departmentLabel;

- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}

-(void) prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
CMGSecondViewController *secondViewController = (CMGSecondViewController *)segue.destinationViewController;
secondViewController.delegate = self;
}

#pragma mark - CMGSecondViewControllerDelegateMethods
-(void) submitButtonActionPerformed:(NSString *) stringValue
{
self.departmentLabel.text = stringValue;
}

@end

Step 7: Run the application to view the delegates do the working. Whatever you will specify in the textfield in the second view controller will be displayed in the main view controller on hit of a button.

So we are done with the show. In hope you enjoyed it !!!. Keep looking forward to more posts.