Cocoa Delegate Design Pattern

Cocoa Delegate Design Pattern

Written By: Debasis Das (18-May-2015)

Cocoa Delegate Design Pattern is a powerful design pattern in which one object works on behalf of another object.

Examples of some of the delegating object in AppKit framework are as follows

  • NSTableView
  • NSOutlineView
  • NSSplitView
  • NSWindow etc

Delegate design pattern provides an alternative to sub-classing

Delegate messages should ideally include (not mandatory) the following verb, should, will or did as a naming convention.

should – In case where the delegate is expected to return a value (BOOL) in case of windowShouldClose:

will – Not expected to return any value, this message is strictly informative and are sent before a change happens

did – Sent after a change has happened. This message is strictly informative and gives the delegate an opportunity to perform processing after a change has happened

Cocoa Delegate Design Pattern NSWindowDelegate

Cocoa Delegate Design Pattern NSWindowDelegate

Example: The figure given below demonstrates how a NSWindow instance sends a windowShouldClose: message to a delegate (in this case the delegate is a subclass of NSWindowController) giving an opportunity to the delegate to respond back.

Cocoa Delegate Design Pattern NSWindowDelegate 1

Cocoa Delegate Design Pattern NSWindowDelegate

When an user clicks on the close button of a NSWindow instance, the window sends the windowShouldClose: message to its delegate. This gives an opportunity to the delegate to defer the closing of the window if the document is edited or there is unsaved data on the screen.

Data Source

Data Sources are identical to delegate, the only difference being instead of being delegated control of the user interface a datasource is delegated control of data.

e.g: NSTableView holds a reference to a datasource (typically a controller) and asks the datasource periodically for the data that it should display.

The datasource like a delegate must adopt a protocol and implement at minimum the required methods of the protocol

Cocoa Delegate Design Pattern Sample Code 1

Cocoa Delegate Design Pattern Sample Code 1

Cocoa Delegate Design Pattern Sample Code 1


//  AppDelegate.h
//  DelegationDesignPatternSampleTwo
//  Created by Debasis Das on 5/18/15.
//  Copyright (c) 2015 Knowstack. All rights reserved.

#import <Cocoa/Cocoa.h>
#import "SliderViewController.h"

@interface AppDelegate : NSObject <NSApplicationDelegate,KSSliderDelegate>

@end
//  AppDelegate.m

#import "AppDelegate.h"
#import "SliderViewController.h"

@interface AppDelegate ()

@property (weak) IBOutlet NSWindow *window;
@property (weak) IBOutlet NSView *sliderPlaceholderView;
@property (weak) IBOutlet NSTextField *sliderValueTextField;
@property (nonatomic,strong) SliderViewController *sliderViewController;
@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
    // Insert code here to initialize your application
    if (self.sliderViewController == nil)
    {
        self.sliderViewController = [[SliderViewController alloc] init];
        [self.sliderPlaceholderView addSubview:self.sliderViewController.view];
        self.sliderViewController.delegate = self; //Here we are setting the delegate for the slider view controller as the App Delegate
    }
}

-(void)sliderValueDidChange:(SliderViewController *)viewController andValue:(float)sliderValue{
    NSLog(@"%s",__func__);
    [self.sliderValueTextField setStringValue:[NSString stringWithFormat:@"%f",sliderValue]];
}

- (void)applicationWillTerminate:(NSNotification *)aNotification {
    // Insert code here to tear down your application
}

@end

//  SliderViewController.h
//  DelegationDesignPatternSampleTwo

#import <Cocoa/Cocoa.h>
@class SliderViewController;

//Declaring a Protocol that must be adhered to by the delegate
@protocol KSSliderDelegate 
-(void)sliderValueDidChange:(SliderViewController *)viewController andValue:(float)sliderValue;
@end

@interface SliderViewController : NSViewController
@property (nonatomic,weak) id delegate;
@end

//  SliderViewController.m
//  DelegationDesignPatternSampleTwo

#import "SliderViewController.h"
@interface SliderViewController ()

@end

@implementation SliderViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do view setup here.
}

-(IBAction)selectSliderValue:(id)sender{
    NSLog(@"%s",__func__);
    [self.delegate sliderValueDidChange:self andValue:[sender floatValue]]; //Here we are asking the delegate to respond to a change in the position of the slider
}
@end



Cocoa Delegate Design Pattern Sample Code 2

Cocoa Delegate Design Pattern Sample Code 2.0

Cocoa Delegate Design Pattern Sample Code 2.0

Cocoa Delegate Design Pattern Sample Code 2.1

Cocoa Delegate Design Pattern Sample Code 2.1

//  ViewController.h
//  ObjectiveCDelegation
//  Created by Debasis Das on 5/3/15.
//  Copyright (c) 2015 Knowstack. All rights reserved.

#import <Cocoa/Cocoa.h>
#import "ContactViewController.h"

@interface ViewController : NSViewController 

@property (weak) IBOutlet NSTextField *selectedContactTextField;

@end


//  ViewController.m
//  ObjectiveCDelegation

#import "ViewController.h"
#import "ContactViewController.h"

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

- (void)setRepresentedObject:(id)representedObject {
    [super setRepresentedObject:representedObject];
    // Update the view, if already loaded.
}

-(void)didSelectContactWith:(ContactViewController *)viewController andContact:(NSString *)contactName{
    [self.selectedContactTextField setStringValue:contactName];
}

-(void)prepareForSegue:(NSStoryboardSegue *)segue sender:(id)sender{
    if ([segue.identifier isEqualToString:@"contactPickerSeque"])
    {
        ContactViewController *viewController = [segue destinationController];
        viewController.delegate = self; //Here we are setting the delegate of the contact view controller as self
    }
}
@end
//  ContactViewController.h
//  ObjectiveCDelegation

#import <Cocoa/Cocoa.h>
@class ContactViewController;

//Declaring a Contact Delegate that must be adhered to by the class which acts as a delegate to Contact View Controller
@protocol ContactDelegate 
-(void)didSelectContactWith:(ContactViewController *)viewController andContact:(NSString *)contactName;
@end

@interface ContactViewController : NSViewController <NSTableViewDataSource,NSTableViewDelegate>

@property (nonatomic,weak) id delegate;

@end

//  ContactViewController.m
//  ObjectiveCDelegation

#import "ContactViewController.h"

@interface ContactViewController ()
@property (nonatomic,strong) NSArray *contactsArray;
@property (weak) IBOutlet NSTableView *contactsTableView;
@end

@implementation ContactViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    self.contactsArray = @[@"Debasis Das",@"John Doe",@"Jane Doe",@"Mary Jane"];
}

- (NSInteger)numberOfRowsInTableView:(NSTableView *)tableView{
    return self.contactsArray.count;
}

- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row{
   
    NSString *strValue;
    strValue = [self.contactsArray objectAtIndex:row];
    return strValue;
}

-(IBAction)selectContact:(id)sender{
    [self.delegate didSelectContactWith:self andContact:[self.contactsArray objectAtIndex:[self.contactsTableView selectedRow]]];
    [self dismissController:self];
}
@end

Download the 2 Sample Codes from the link given below

Slider Value changes delegated to AppDelegate to display DelegationDesignPatternSampleTwo

Contact Picket Implementation using Delegate Design Pattern ObjectiveCDelegation

Posted in Cocoa, Design Pattern, iOS, Objective C Tagged with: , , , , ,

Leave a Reply

Your email address will not be published. Required fields are marked *

*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

Recent Posts


Hit Counter provided by technology news