 # Understand and Use Closures in Swift

Have you ever seen some factory method in UIKit and see this strange parameter called `completion` or `completionHandler`? Usually you put `nil` there and leave it alone. These strange things like `(Double,Double) -> Bool` things are closures. Closures are functions you use as types, often in parameters of other functions. In this lesson we’ll explore closures and get under the hood to explain what they are and what they are really doing.

# Set Up a Playground

Set up a playground in Xcode, the iPad or on the web at the IBM Swift Sandbox. IF using the IBM Swift Sandbox, make sure you have Foundation imported.

`import Foundation`

# The Basics of Closures

Suppose I want to calculate the volume of a deep dish pizza. Add these functions to the playground:

``` //area of a round pizza
func roundArea(radius:Double) -> Double{
}
//volume of a round pizza
func roundVolume(height:Double, radius:Double ) -> Double{
}
```

Add a variable to compute the volume of a pizza of radius 6 and height 2, then print it

```var volume = roundVolume(height:2,radius:6)
print( String(format:"Round volume %4.2f",volume))
```

Run this and get the volume from the area on the console. Which is fine if I had only round pizzas. What if I had rectangle, oval or triangle pizzas? I’d have to write two new functions each: one for the area and one for the volume. However in each case I’m only changing the area calculation. What if I could pass just the calculation to the volume function? That’s what a closure is: a way of writing something like a function but assigning it as a type. Add the function to the class.

```func volume(
height:Double,
dim1:Double,
dim2:Double,
area:(Double,Double) -> Double) -> Double
{
return area(dim1,dim2) * height
}
```

Look at the parameter `area`. I’ve declared it `(Double,Double) -> Double`. That looks a lot like a function that returns `Double`, and two `Double` parameters. That’s what a closure does as a type. A closure gives a skeletal structure like a function you can pass as a parameter. Below the `volume` function add the following line of code.

```let rectangleArea = { (length:Double,width:Double) -> Double in
return length * width
}
```

When I declare the contents of the identifier, I flesh out something like a function inside of curly braces. Instead of `func` before the parameters, I put `in` after the return type. There are parameters `(length:Double,width:Double)`. I have the return type as a `Double`. For closures, there must always be a return value. If you don’t have one mark it `Void` or `()`.

Since I declared the type in the closure declaration, I often can remove it from the declaration

```
let  rightTriangleArea = {(length,width) -> Double in
return length * width / 2.0
}
let ovalArea = {(length,width)->Double in
return length/2.0 * width/2.0 * M_PI
}```

It doesn’t work in all cases though. This give an error if you do not specify the type

```let roundSliceArea = { (radius:Double, slices:Double) ->Double in
return M_PI * radius * radius / slices
}
```

I can use the same volume function and change how I compute the area.

```print (volume(height: 2,dim1: 10, dim2: 12, area:rectangleArea))
print (volume(height: 2,dim1: 10,dim2: 12, area:roundSliceArea))
print (volume(height: 2,dim1: 10, dim2: 12, area:rightTriangleArea))
print (volume(height: 2,dim1: 10, dim2: 12, area:ovalArea))
```

I do have a problem with a circle. I could define it like this in my storyboard:

``` let circleArea = {(radius)->Double in
}
print (self.volume(height: 2,dim1: 10, dim2: 12, area:circleArea))
```

This doesn’t work for the circle, because the number of parameters are different. You’d get this error message
`Cannot convert value of type '(Double) -> Double' to expected argument type '(Double, Double) -> Double'`

You have choices: Use the oval with the same length and width or a placemarker.  I tend to choose the place marker. Change `circleArea` to add the extra parameter. Fix the above code to this:

```let circleArea = {(radius:Double, placeMarker:Double) -> Double in
}
print (volume(height: 2,dim1: 10, dim2: 12, area:circleArea))
```

# Literal Closure in Parameters

You don’t have to assign the closure to a constant. You can write it explictly in the function. For a rectangle area, you can write this in the playground.

```
volume = volume(
height: 2,
dim1: 10,
dim2: 12,
area: {(width,length)->Double in
return width * length
}
)
print(volume)
```

You’ll find this a very common way of specifying the closure. When the closure is the trailing parameter, you can place it after the function like this:

```volume =  volume(
height: 2,
dim1: 10,
dim2: 12)
}
print(volume)
```

# Closures as Completion Handlers

One very common use of closures is completion handlers. Make a new function like this:

```func volume(
height:Double,
dim1:Double,
dim2:Double,
completionHandler:(Double)->()
){
let result = dim1 * dim2 * height
completionHandler(result)
}
```

Neither the `completionHandler` closure nor the `volume` function returns anything. Instead the result is the parameter of the completion handler.
Why would anyone do this? The reason is asynchronous processing. There are methods which Apple or the developer don’t want to run in the main thread. If you are querying a database, or opening a file any results appear in a closure. The database query might take some time, and you don’t want the rest of your application to freeze while you wait for the result. Similarly, while loading a file you don’t want to freeze the system waiting to learn if the load was successful.
Instead of `return` in these functions, the method runs on another thread at its own pace and lets the main thread go on its merry way. When done, the method calls something like `completionHandler`, `handler`, or `completion` with the results it returns as the completion parameter.

The developer uses the result their implementation of the completion handler. This is why most often closures happen completely within a function call. Usually they are specific to the code around it. For example, the `volume` function with the `completionHandler` would code like this to save the result to the volume property and output the result.

```volume(height: 2,dim1: 10,dim2: 12)
{(result)->() in
print(result)
volume = result  //in a class use self
resultLabel.text = String(format:"Completion %5.2f")
}
```

Completion handlers often pass off the value to a property in a class, like the code above assigns the value of  `result` to `volume`. If you run the code above within a class, be sure to include the class identifier or `self`. `volume = result` should be `self.volume = result`. The identifiers within a closure have no scope to the class. They must be explicitly stated.

# A Real Example of a Completion Handler

As a general rule, you’ll find completion handlers when you don’t know when you will complete a task. One good example of this is presenting alert views.

Set up a new single view project named ClosureDemo, with Swift as the language. Go to the storyboard and drag a label and button.

Set the font on both to Title 1.  Select the button. Title the button Alert. Click the alignment icon in the auto layout menu bar. Check Horizontally in Container and Vertically in container.  Change Update from to Items of new constraints like this: Click Add 2 constraints.  Select the Label. Title it Results.  Click the pin icon in the auto layout toolbar.  In the dialog box that appears type 10 then tab, 10 then tab and 10 then tab. Click down to the bottom and Update frames with Items of New Constraints. Click Add 3 constraints.

Open the assistant editor and control-drag the label to the code. Name the outlet resultsLabel. Control-Drag from the button to the code. Change to an action. Name the action presentAlert.

Close the Assistant editor.  Open the `Viewcontroller.swift` code.

In the `presentAlert` action, add the following code:

``` @IBAction func presentAlert(_ sender: UIButton) {
volume = 240.0
//example of a real completion handler.
message: "Volume is \(volume)",
```

Alert actions only activate after the alert shows and the action’s button gets tapped by the user. The `UIAlertAction` initializer uses handlers to describe the action when pressed. Add this to the compute action:

```
let clearAction = UIAlertAction(
title: "Clear", style: .destructive,
handler: {(action)->() in
self.volume = 0
self.resultLabel.text = "Cleared"
}
)
```

In `clearAction`, the user sets the `volume` property to 0 and reflects that in the Label.  Again, the closure is independent of the scope of its class. You must specify `self` in order to use the `ViewController` classes’ properties and methods.

Add two more examples of actions:

```
let doubleAction = UIAlertAction(
title: "Double",
style: .default,
handler: {(action)->() in
self.volume *= 2
self.resultLabel.text = "\(self.volume)"
})
let cancelAction = UIAlertAction(
title: "Cancel",
style: .cancel,
handler:{(action)->() in
self.resultLabel.text = "\(self.volume)"
})
```

```alert.addAction(clearAction)
```

Finally present the alert controller. `present` has a completion handler. Add a `print` statement to it to see it in action, then a `print` after the `present`.

```
present(alert, animated: true, completion:
{()->Void in
print ("present Completed")
})
print ("Outside Handler")
```

Build and run. Tap the Alert button. You get the alert. The console printed this:
``` Outside Handler present Completed ```
After calling `present`, The system executed the next step, and did not wait for it to finish printing  Outside Handler. Once the presentation completed, the system printed present Completed. The alert shows: Tap the double button. The label reads 240. Try the other buttons. You’ll find closures in most often in these handlers. Anything that takes and unpredictable amount of time will use a handler in a closure.

# The Whole Code

You can find the code for this tutorial on the IBM Swift Sandbox. For cutting and pasting into an Apple Playground on iPad or Xcode, Use the code below.

```//
// Closure Demo file
// For MakeAppPie.com  closure tutorial
// Sep 2016 by Steven Lipton
//
//
import Foundation

//area of a round pizza
func roundArea(radius:Double) -> Double{
}
//volume of a round pizza
func roundVolume(height:Double, radius:Double ) -> Double{
}
var volume = roundVolume(height:2,radius:6)
print( String(format:"Round volume %4.2f",volume))

//Closure to change the area formula
func volume(
height:Double,
dim1:Double,
dim2:Double,
area:(Double,Double) -> Double) -> Double
{
return area(dim1,dim2) * height
}

//Assigning type (Double,Double) -> Double to Classes

let rectangleArea = { (length:Double,width:Double) -> Double in
return length * width
}
let  rightTriangleArea = {(length,width) -> Double in
return length * width / 2.0
}
let ovalArea = {(length,width)->Double in
return length/2.0 * width/2.0 * M_PI
}
let roundSliceArea = { (radius:Double, slices:Double) ->Double in
return M_PI * radius * radius / slices
}
//Trying out the volume function

print (volume(height: 2,dim1: 10, dim2: 12, area:rectangleArea))
print (volume(height: 2,dim1: 10,dim2: 12, area:roundSliceArea))
print (volume(height: 2,dim1: 10, dim2: 12, area:rightTriangleArea))
print (volume(height: 2,dim1: 10, dim2: 12, area:ovalArea))

//Fitting a single parameter formula with a placemarker
let circleArea = {(radius:Double, placeMarker:Double) -> Double in return M_PI * radius * radius }
print (volume(height: 2,dim1: 10, dim2: 12, area:circleArea))
// closure within parameters
volume = volume(height: 2, dim1: 10, dim2: 12, area: {(width,length)->Double in return width * length})
print(volume)
// Trailing closure outside parentheses
volume =  volume(height: 2, dim1: 10, dim2: 12) {
}

//Closures as Completion Handlers
func volume(
height:Double,dim1:Double,dim2:Double,
completionHandler:(Double)->()
){
let result = dim1 * dim2 * height
completionHandler(result)
}

// For asynchronous processing, use the closure instead of returning the result.
volume(height: 2,dim1: 10,dim2: 12)
{(result)->() in
print(result)
volume = result

}

```

## The ClosureDemo Alert project

This is the code for the ClosureDemo Alert project. Add the label and button as described above than connect to this code in ViewController.

```//
//  ViewController.swift
//  ClosurePlay
//
//  Created by Steven Lipton on 9/9/16.
//

import UIKit

class ViewController: UIViewController {

var volume = 0.0

@IBOutlet weak var resultLabel: UILabel!
@IBAction func compute(_ sender: UIButton) {
volume = 240.0
//example of a real completion handler.
message: "Volume is \(volume)",

let clearAction = UIAlertAction(
title: "Clear", style: .destructive,
handler: {(action)->() in
self.volume = 0
self.resultLabel.text = "\(self.volume)"
})

let doubleAction = UIAlertAction(
title: "Double",
style: .default,
handler: {(action)->() in
self.volume *= 2
self.resultLabel.text = "\(self.volume)"
})
let cancelAction = UIAlertAction(
title: "Cancel",
style: .cancel,
handler:{(action)->() in
self.resultLabel.text = "\(self.volume)"
})

present(alert, animated: true, completion: {()->Void in
print ("In present Handler")
})
print ("Outside Handler")

}

override func viewDidLoad() {
1. 