iOS Design Patterns: Delegation

Knowing what design pattern to implement in your code is one of the most important skills to have as a competent iOS developer.

No, design patterns have nothing to do with user interface or visual design-who would ever think that? -scratch head- Rather, they are reusable solutions that solve common problems, particularly with communication between objects in code.

There are many powerful design patterns found in iOS development. For this blog post, I wanted to expand on the delegate pattern in iOS.


What it delegation?

Delegation is a variation of a common design pattern in object oriented programming known a decorator pattern, in which a user can ‘wrap’ additional functionality to an object without interfering its class structure.

Pertaining to iOS, delegation is a mechanism in which one object acts on behalf of another object. It allows objects to avoid subclassing from a ‘parent’ class just to inherit it’s parent’s capabilities. Inheritance patterns make a child object highly dependent of its parent, which is considered ‘tight coupling’. As a result, the single responsibility principle and separation of concerns between these classes begin to blur, and that’s bad.

How delegation fixes that.

Delegation remedies tight coupling because the only thing binding two objects together then is simply an agreement that the delegate object will implement certain methods that fulfill a particular responsibility. A perfect example of delegation found in iOS programming is the relationship between UITableView and UIViewController.
A UITableView is not aware of how many rows and sections it should present; it just knows that it has to present some visual representation of a table view, which is really just an ordered set of data. The task of providing table view values such as number of rows, sections, and cell height is designed for the UITableView delegate, which is usually a UIViewController that says, “I will be in charge of displaying specific data to your table view.” We achieve that by setting the view controller as the table view delegate like this.

[code language=”objc”]
self.tableview.delegate = self
[/code]

This powerful relationship between UITableView and UIViewController is considered very loose- and within computer programming, that’s a wonderful thing because it allows our view controller to be more versatile in the future. After all, it can be the delegate not just for tableviews, but scrollviews, search bars, keyboards, etc.


Implementation.

We covered how powerful delegating tasks can be without directly inheriting from a parent class just for its desired functions. Let’s consider how we’re going to get on object like UIViewController to implement methods and functionality from an otherwise incompatible object like UITableView. This is where Protocols come in.

Protocols.

A protocol is exactly what it means in the real world: a set of procedures, a system of rules, some official agreement between parties. When you define a protocol with functions, any object that ‘conforms’ to that protocol must implement its functions.

Well, that’s not entirely true.

In Objective-C, you had the option of declaring which protocol function implementations were required and optional. With Swift, there is currently no official way to do that. You can write an Objective-C or Swift protocol depending on what suits you.

In Swift, this is how a protocol is defined:

[code language=”objc”]
protocol LeoProtocol {
func coolFunction()
}
[/code]

Here is an implementation of a class conforming to the LeoProtocol:

[code language=”objc”]
class someClass: LeoProtocol {
func coolFunction() {
// implementation of this protocol function
}
}
[/code]

However, if you want to define a protocol with optional methods in Swift, you will need to declare an Objective-C protocol; the directive looks like this:

[code language=”objc”]
@objc protocol LeoProtocol {
func coolFunction()
optional func coolOptionalFunction()
}
[/code]


Summary

In short, the general steps to defining a protocol in Swift are:

  1. Write out your a protocol functions
  2. Add a delegate property specifying the type as the protocol
  3. Assign any object that conforms to the protocol to that delegate property

Feel free to comment below if you think there’s anything I missed or should clarify.

The next design pattern post will be about the Observer.


Leave a comment

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