What is Delegation? – A Swift Developer’s Guide

Of the major design patterns that are prevalent in iOS development, delegation is one that appears quite often. For many developers entering app development for the iOS platform, dealing with delegates is a new concept. It certainly was for me.

In my analysis of NSNotificationCenter vs Delegation, I wrote some about delegation, but only in comparison to how NSNotificationCenter works. I haven’t yet given delegation dedicated time and analysis, but I intend to do so now.

My aim in this blog entry is to try and make some sense out of the question, “What is delegation?”. Explore with me…

What is the delegation design pattern?

To read that “delegation is a design pattern that [insert explanation here]” never really clicked with me. Many who are new to programming have not dealt extensively with “design patterns”, so it doesn’t always suffice to define delegation in those terms.

I suspect that since Swift has lowered the barrier to entry for iOS development, many who are new to the platform are also new to coding in general, so here’s my attempt to explain what clicked for me regarding what delegation is:

Design pattern

First, take the phrase “design pattern”.

Design implies architecture. It connotes a strategy for organizing something. Design conveys the method by which components will work together to accomplish an end.

Pattern implies that there is some repeatable process that has honed in around a common thread… a common practice… a predictable method for doing something. “Pattern” gives the impression that such a practice has converged over time into something that is now well-known, well-understood, and commonly used. I imagine a sort of “survival of the fittest” approach to process and practice. Things that didn’t converge or that were weaker in the real world fell away and the strongest survived into this thing we call “pattern”.

A design pattern in software terms, then, is a method for architecting, strategizing about, and organizing an application’s code in such a way that has been found to be commonplace, repeatable, and practically sound over time.

Delegation

Now take the word delegation. Three things come to my mind:

  1. The verb, “to delegate”, meaning “to give control”
  2. The noun, “a delegate”, meaning “a person acting for another”
  3. The made-up noun, “a delegat_or_”, or more properly, a principal, meaning “a person who delegates to another”

In the real world, the word delegation encapsulates relationship and responsibility. A delegator/principal (noun) would delegate (verb) control or responsibility to another person called a delegate.

How could we map this to software? Well, it actually falls in line quite nicely.

Rather than people, we’re dealing with instances of classes (or other data structures like structs, but I’m just going to keep it simple and say “class” to encapsulate the idea). For delegation to occur in software, you’d have a situation where one class (a delegator/principal class) would delegate control or responsibility, here meaning behavioral logic, to another class called a delegate.

How is delegation used?

So yes… delegation is a design pattern. It’s a design pattern that exists on other platforms, but it is one that has been heavily adopted by Apple and is ubiquitous throughout the iOS APIs. It’s a design pattern that shifts responsibility from one class to another, thereby creating a separation of responsibilities and concerns. But what kinds of responsibilities and concerns? How is delegation used in practice?

Communication

In practice, delegation is most often used as a way for one class to communicate to another class. Observing some of the actions that delegates perform from Apple’s own APIs give us clues about this. Take the following samples from UITableViewDelegate as an example:

  • tableView(_:_will_SelectRowAtIndexPath:)
  • tableView(_:_did_SelectRowAtIndexPath:)
  • tableView(_:_did_HighlightRowAtIndexPath:)

Or how about a sampling from UIScrollViewDelegate:

  • scrollView**Did_Scroll**(:)
  • scrollView**WillBegin_Dragging**(:)
  • scrollView**WillEnd_Dragging**(:withVelocity:targetContentOffset:)
  • scrollView**DidEnd_Dragging**(:willDecelerate:)

My observation of Apple’s APIs indicates to me that one of the intended uses for delegation is to allow one instance to communicate back to some other instance that something will/did happen. The table view or scroll view delegates the opportunity to perform some action in response to some lifecycle event to another class, namely, its delegate.

It’s also worth noting the scope of the communication that delegation is intended to be used for. Whereas NSNotificationCenter fits the need for one instance to broadcast a message intended for more than one listening instance, delegation fits the scenario where an instance only needs to send a message to a single listener (the delegate).

Customization

Another common usage for delegation is to provide a delegate instance the opportunity to customize certain aspects of the delegat_ing_ instance’s internal state. Once again, clues from a few of Apple’s APIs shed some light on this usage scenario. Let’s look at UITableViewDelegate first:

  • tableView(_:heightForRowAtIndexPath:)
  • tableView(_:editActionsForRowAtIndexPath:)
  • tableView(_:indentationLevelForRowAtIndexPath:)
  • tableView(_:shouldHighlightRowAtIndexPath:)

These are all customization-points that a UITableView allows its delegate to have a say in. Some of the methods are so important that the table view can’t display itself unless it gets this information from its delegate. The point here is that the table view is shifting responsibility for the implementation of that logic off to its delegate, allowing for greater controlled flexibility and customization.

Wrapping up

With delegation being such a heavily utilized strategy for organizing an iOS application’s logic, understanding what it is becomes key concern. In this article we unpacked the terms “design pattern” and “delegation” to get a grasp of why those words were chosen to describe the strategy. Finally, we looked at how the delegation pattern is used in practice, observing that two common use-cases for delegation: class-to-class communication and customization.

comments powered by Disqus