Understand Closures

You’ll find closures throughout the API’s, but you may not know how to use them properly. Let’s take a basic tour of closures.

Download the exercise file, and you’ll find a project with a playground. In the playground you’ll find a function  to compute a pizza volume.

```func roundPizzaVolume(height:Double, diameter:Double) -> Double{
let pi = Double.pi
let z = diameter / 2.0
let a = height
let v = pi * z * z * a //My favorite pun.
return v
}
roundPizzaVolume(height: 2, diameter: 10) ```

That’s for a round pan pizza, for a rectangle it won’t work.

But if I make a function that has a formula for the area, then I can do any area. In the `anyPizzaVolume`, I’ll put one at the end of the argument list.

`anyPizzaVolume(height:Double, length:Double, width:Double, area:(Double,Double)->Double)-> Double{`

That declares a closure, which is not much more than a function that you pass as a parameter.

In my code I’ll multiply height by area, then return the volume.

```func anyPizzaVolume(height:Double, length:Double, width:Double, area:(Double,Double)->Double)-> Double{
let volume = height * area(length,width)
return volume
}```

I’ll call `anyPizzaVolume.`In the autocomplete for `anyPizzaVolume`, you’ll see the closure.

`anyPizzaVolume(height: , length: , width: , area:  Double>)`

Add a height of 2, a length of 10 and a width of 10. Hit tab when you get to area, and you’ll get a stubbed closure. I usually use this, but I’m going to do it manually so you get the idea. You stick the closure as the last parameter, so you can put the closure outside the function. Otherwise you need to put it inside, and that can get confusing to read.

```anyPizzaVolume(height: 2, length: 10, width: 10) {

}
```

You start a closure identifying the declared variables, then add the keyword in

```anyPizzaVolume(height: 2, length: 10, width: 10) {
(l,w) in
}
```

Now you write code based on those two values.

```anyPizzaVolume(height: 2, length: 10, width: 10) {
(l,w) in
let r = l / 2.0
return r * r * Double.pi
}
```

Run this and you get the answer you got before.  I can copy this, paste it, and change the code to a rectangle area.

```anyPizzaVolume(height: 2, length: 10, width: 10) {
(l,w) in
return l * w
}```

Run again, and you get a different answer. There are better ways of doing this method, but I wanted to illustrate the basic use of closures. Where they get used is Asynchronous processing. That’s when you don’t control when the code will execute like completion handlers, timers,  and actions. For example, in the `roundPizzaVolume` I could add a completion handler that handles errors.

`completionHandler:(Bool,Double)-> Void`

For this closure, I’m not returning anything to the function. Closures require a return type, so I use`Void` to indicate there is noting returned. I’ll add the `completionHandler``function to to the code

`completionHandler(v>0,v)`

The bool indicates if the area is a meaningful answer, and I pass the volume to the closure. Now I can change the roundPizzaVolume code to use the closure by adding this:

```roundPizzaVolume(height: -2, diameter: 10){
(success,volume) in
if !success{
print("Invalid Volume \(volume)")
}
}
```

Change the height to -2 and Run. Many closures, especially file handling, will do this and give you a success bool which you can then handle after it does it function.

Take a look at the `ViewController`.  You’ll find examples of  API’s using closures.   Action handlers are often closures. For example I have an alert in this code. `UIAlertAction`s use closures to respond to the selection of the action.

let actionOne = UIAlertAction(title: “First Action”, style: .default) { (action) in
}

Notice that as asynchronous blocks, you need `self` to use properties and methods of the class.  Also you can make closures optional, so if you do not want to use them, they can be set to nil, as in this action.

` let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)`

There’s a lot you can do with closures. As you can see here, you will find them in code frequently.

The Whole Code

You’ll find the completed code on Github here. Below you’l find the playground and view controller for this project.

```import UIKit
//
//  An exercise file for iOS Development Tips Weekly
//  For videos go to http://bit.ly/TipsLinkedInLearning
//  For code go to http://bit.ly/AppPieGithub
//

func roundPizzaVolume(height:Double, diameter:Double, completionHandler:(Bool,Double)->Void) -> Double{
let pi = Double.pi
let z = diameter / 2.0
let a = height
let v = pi * z * z * a //My favorite pun.
completionHandler(v>0,v)
return v
}
roundPizzaVolume(height: -2, diameter: 10){
(success,volume) in
if !success{
print("Invalid Volume \(volume)")
}
}

func anyPizzaVolume(height:Double, length:Double, width:Double, area:(Double,Double)->Double)-> Double{
let volume = height * area(length,width)
return volume
}

anyPizzaVolume(height: 2, length: 10, width: 10) {
(l,w) in
let r = l / 2.0
return r * r * Double.pi
}

anyPizzaVolume(height: 2, length: 10, width: 10) {
(l,w) in
return l * w
}

```
```//
//  ViewController.swift
//  ClosureExercise
//
//  An exercise file for iOS Development Tips Weekly
//  For videos go to http://bit.ly/TipsLinkedInLearning
//  For code go to http://bit.ly/AppPieGithub
//
import UIKit

class ViewController: UIViewController {

@IBOutlet weak var presentStatus: UILabel!
@IBAction func alertButton(_ sender: UIButton) {
//Actions for methods like alerts often use closures to do the action
let actionOne = UIAlertAction(title: "First Action", style: .default) { (action) in
//This is on a seperate thread so use self to access the elclosing class' methods and properties.
//this is on a seperate thread so use self to access the elclosing class' methods and properties.
}
let actionTwo = UIAlertAction(title: "Second Action", style: .default) { (action) in
//This is on a separate thread so use self to access the enclosing class' methods and properties.
}
// Closures can be optional, and then you can set the value to nil if you don't plan to use it. Make sure you handle the nil in the method though.
let cancelAction = UIAlertAction(title: "Cancel", style: .cancel, handler: nil)

// The present function has a closure we usually leave nil, but if you have clean up​ after you launch the method, this is where you do it. Here I print a status message.
}
}