Don’t abuse Delegates, Use Swift Closures Instead

Please find the most recent version here.

As iOS developers, we tend to use a lot of delegates, sometimes even abuse of these poor little fellas. But, what else can we use? Right?

We know a few other options, but they might feel awkward or a bit of an overkill, depending on what we want to accomplish.

Real World Example

If you’ve been programming in iOS before the introduction of the (iOS 8), you probably used its predecessor alert, . One of the most noticeable changes between these two alerts is the way they interact with their caller. The notified the view controller about the button events using delegates, while the uses a closure of type . In my opinion, this change was a significant improvement, which provides developers a cleaner way to implement the alert.

In this tutorial, we will create a simple “note taking” (almost useless) app, and we will be using the closure pattern as an alternative to the frequently used, practically abused delegate pattern.

What you’ll need for this tutorial

  • Xcode 8 or higher
  • Swift 3 or higher
  • A bit of experience working iOS
  • High-level understanding of swift optionals

Let’s Create Our Project

Create a new Xcode project.

I will name it .

Command + n to add a new file. This file will be a subclass of an .

and call it

Now we need to go to the storyboard and add a new , change the custom class on the “Identity Inspector” to and set the“Storyboard ID” to .

Awesome!

We now have our main project all set up.

What we’ll Build

Now that we have our project all set let’s discuss a bit what we’ll be doing.

The project will have two views.

The first view controller() will contain a and a .

  • The button will present the
  • The label text will be updated from the

The second view controller () will contain a and two (one to cancel and the other one to update label).

  • The text field will get the input from the user
  • The button will dismiss the current view controller
  • The switch will notify the if the text from the text field on should update the label

Ok, that’s enough. Let’s start building this!

We’ll start by adding the and the to by adding the following code on top of the method.

Now, let’s add some layout constraints so the and the .

Create a new private method call as follow:

Now, override the method, and add the , the and the method we just created.

Great! Now let’s add a function to present the .

Awesome!

By now, your should look like this:

Now, let’s run our project. You should see something exactly like this.

Awesome! Is not a pretty design, but it’ll work.

Now, this is our :

As you can see above, I added a few controls, the and two .

Also, added two methods, and . The will dismiss and will notify the caller about the action. Is important to notice that all method logic will be handled by the caller (in this scenario the ).

But, what the heck is the ?

The variable is of type meaning the variable is a function (just like blocks in Objective-C). This approach is possible in swift because functions are first class citizens (often call first class objects). But don’t worry, to use them you need to understand what they can do, how to create one and how to use them.

Let’s discuss each part of our type: . To make it very clear, let’s identify each part of it.

  • : this means that can pass on an optional (can have a string or be nil).
  • : identifies the “arguments” and what is the “returned” (just like functions). We’ll only work with the first part (the arguments).
  • : this is equivalent to . It says that nothing is expected.

Is important to notice that is an optional, therefore not necessarily needs to implement the variable. In case the variable is not implemented (), the will only be dismissed.

Great! Now, let’s use this pattern to pass information from to .

Implementing Swift Closures to Pass Data Between UIViewControllers

Let’s implement the variable on the . Add the following code on the method just on top of the line.

If you try to run your code now, you should get an error like this one:

This means that we need to add the Objective-C extremely used on our variable. To avoid a reference cycle, instead of referencing directly, we will use capture list and reference instead.

But… why? Is not required anywhere else on the .

Right, is not required anywhere else on the , but we are now inside our closure declaration, and inside closures, you need to reference . Is a good practice to use , , or the property that you will reference inside the closure ( in this especific case) to avoid reference cycles. If you use the property instead of or , you don’t need to use .

OK…

Great!

By now the error must have disappeared and you should be able to run the project and test everything you just did.

Coming back to our , as we mentioned before, it is a closure, and closures are like functions.

So, we declare the variable to a function with a variable and a return value of type , which is the same as .

Conclusion

Most of the time IOS programmers overuse delegates since they don’t like very much the Objective-C block syntax (not my case, I used to loved that weird syntax). This article demonstrated that it is possible to use a closure to pass information from one view controller to another. This approach provides iOS developers a viable alternative to those good ol’ Delegates.

— — — — — — — —

We just used closure to pass information from one view controller to another. As iOS developers (and if you are coming from Objective-C), we sometimes used the Delegate pattern a lot.

Most of the time it was because some people didn’t like very much the Objective-C block syntax (not my case, I used to love that weird syntax).

Now, with Swift closures, we can set aside those good ol’ Delegates.

Download project

Follow me

Twitter: dmlebron

iOS Engineer