What are Swift Extensions?

Extensions add new functionality to an existing class, structure, enumeration, or protocol type. This includes the ability to extend types for which you do not have access to the original source code (known as retroactive modeling). Extensions are similar to categories in Objective-C. (Unlike Objective-C categories, Swift extensions do not have names.) - The Swift Programming Language

It’s important to note that while Extensions can add new functionality to a type, they can’t override existing functionality.

Using Swift Extensions

Declare extensions with the extension keyword

extension UIViewController {

}

When we define an extension to add new functionality to an existing type like UIViewController, the new functionality will be available to all existing UIViewController’s throughout our project.

Adding functionality

In one of my projects I found Swift Extensions to be handy by extending UIViewController to hide a keyboard or display an error.

extension UIViewController {

func hideKeyboardWhenTappedAround() {
let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(UIViewController.dismissKeyboard))
view.addGestureRecognizer(tap)
}

func dismissKeyboard() {
view.endEditing(true)
}

func displayError(error: NSError) {
dispatch_async(dispatch_get_main_queue()) {
let alert = UIAlertController(title: "Error", message: error.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert)
let action = UIAlertAction(title: "Ok", style: UIAlertActionStyle.Default, handler: nil)
alert.addAction(action)
self.presentViewController(alert, animated: true, completion: nil)
}
}
}

I had multiple UIViewController’s throughout my project with UITextField’s so adding the functionality in an extension saved me from having to write hideKeyboardWhenTappedAround() over and over in each ViewController.

Along with my displayError() function which was called just in case something with the network went wrong. I needed to somehow tell the ViewController to display the error and again, adding the functionality via a UIViewController extension was the best solution I came up with.

Computed Properties

Extensions can add computed instance properties and computed type properties to existing types.

In our example we’ll extend Double to convert temperatures.

extension Double {
var CelciusToFarenheit: Double { return (self * 9/5) + 32 }
var CelciusToKelvin: Double { return (self + 273.15) }
var FarenheitToCelcius: Double { return (self - 32) * 5/9 }
var FarenheitToKelvin: Double { return (self + 459.67) * 5/9 }
var KelvinToFarenheit: Double { return (self * 9/5) - 459.67 }
var KelvinToCelcius: Double { return (self - 273.15) }
}

var farenheitValue: Double = 78
var celciusValue: Double = 30
var kelvinValue: Double = 300

print("\(farenheitValue) degrees Farenheit is \(farenheitValue.FarenheitToCelcius) degrees Celcius")
print("\(farenheitValue) degrees Farenheit is \(farenheitValue.FarenheitToKelvin) degrees Kelvin")

print("\(celciusValue) degrees Celcius is \(celciusValue.CelciusToFarenheit) degrees Farenheit")
print("\(celciusValue) degrees Celcius is \(celciusValue.CelciusToKelvin) degrees Kelvin")

print("\(kelvinValue) degrees Kelvin is \(kelvinValue.KelvinToFarenheit) degrees Farenheit")
print("\(kelvinValue) degrees Kelvin is \(kelvinValue.KelvinToCelcius) degrees Celcius")

78.0 degrees Farenheit is 25.5555555555556 degrees Celcius

78.0 degrees Farenheit is 298.705555555556 degrees Kelvin

30.0 degrees Celcius is 86.0 degrees Farenheit

30.0 degrees Celcius is 303.15 degrees Kelvin

300.0 degrees Kelvin is 80.33 degrees Farenheit

300.0 degrees Kelvin is 26.85 degrees Celcius

We could definitely use some string formatting here

Why even use Extensions?

As I learn more about using Extensions I’ll be sure to update this post.

Using Extensions we can extend classes we don’t have the source code for which is really great because even though we can come up with other ways to solve our problems, Extensions helps us follow the Don’t Repeat Yourself principle.

You can find a lot of handy Extensions by @jasdev either by following @PublicExtension or on the Public Extension GitHub