I am the author of iOS 17 Fundamentals, Building iOS User Interfaces with SwiftUI, and eight other courses on Pluralsight.
Deepen your understanding by watching!
The 5 W’s of Swift Extensions
For newcomers to Swift, the concept of extending a Type may be new, so I thought I’d share a high-level overview of Swift extensions in the style of asking the 5 W’s: Who? What? When? Where? Why?
Who
“Swift developers” is a pretty obvious answer, but here are a scenarios to ask yourself about to see if you could make use of Swift extensions:
- “I am relying on Types that are found in 3rd party frameworks or libraries and I wish I could add a little bit of functionality that isn’t there out of the box. Can I do that easily?”
- “In utilizing Apple’s frameworks I find that a Type could be more powerful if it could just do [x]. Can I add that power to the Apple framework Type?”
- “I have written a framework for myself / my team that is used in multiple apps, but I desire to add behavior to one of the framework’s Types that is only relevant in a specific area of one particular app. Can I add that special functionality without changing the framework source?”
If you related to any or all of those scenarios, you could potentially make use of Swift extensions to speed your workflow and make your more organized and clean. Read on for more!
What
Extensions add new functionality to an existing class, structure, or enumeration type.
– Apple Swift Developer Reference
The key word is existing. Hopefully the scenarios listed under “Who” make a little more sense with this information in mind. In all of those cases, you wish to add functionality to Types that have already been designed and implemented.
What I have found to be amazing about Swift extensions is that the word “existing” also applies to Types for which you don’t have access to the original source code. That is powerful!
So extensions are especially useful if you want to add behavior to a Type found in any of the Cocoa / Cocoa Touch frameworks, or a 3rd party’s framework. Additionally, if you’ve created your own libraries and frameworks and you’d like to add behavior without modifying the original source, extensions are a good choice for adding that behavior, especially if what you’re adding doesn’t apply to every single usage of the Type you’re extending.
When
The most logical time to use Swift extensions is when you have a piece of functionality that you want to be able to reuse, and the most reasonable place to put that code is within an already-existing Type. Ideally, the piece of functionality is so closely related to that Type that it just makes sense to extend that Type’s behavior to include your new functionality… “If only I could peek inside that Type’s implementation to inject my new code”, you think to yourself.
If you’re pondering along those lines, then chances are, Swift extensions will aid you in your effort to create more reusable, clean, and organized code.
Perhaps a good question to ask here is, “When not?”. When I see phrases like, “most reasonable place to put that code”, it begs the question, “What does ‘most reasonable’ mean?”. The answer isn’t black and white. I’ll offer what I’ve done in the past as general advice:
As a general rule of thumb, extensions are great for small, simple additions to a Type, rather than long, complex functionality.
If you’re implementing a set of behavior (more than a handful of methods or computed properties), creating a new Type to encapsulate that behavior is most appropriate. After all, that’s what classes and structs do. When deciding on extension vs new Type, they key word that comes to my mind is relatedness. How related is this behavior to the Type I think I want to extend?
Additionally, extensions are limited in the area of maintaining state. Extensions cannot add new stored properties (only computed ones). Creating a new Type to encapsulate the stored properties and the behavior that utilizes them is your alternative solution in this case.
Where
So you’ve decided that you want to create an extension to some class, struct, or enumeration. Where do you put it? My thought on this has always been to create a new .swift file, give it a name that indicates which Type you’re extending, and create the extension inside that file.
So if I want to extend, say, String to have a new method called “sayHello” which printed “Hello” when invoked, I would create a new .swift file called StringExtensions.swift. I’d then place my extension inside:
1extension String {
2 func sayHello() {
3 println("Hello")
4 }
5}
Hey, awesome – you got a bonus How with that quick example! Creating an extension in Swift is that easy.
Why
- Swift extensions are powerful. They empower you to add behavior to any class, struct, or enumeration, even if you don’t have access to the original source code.
- They are simple and convenient to create.
- They encourage code re-use by encapsulating behavior that will be used more than once in your project in a single location.
- Additionally, they promote good code organization, leading to cleaner and more readable code when used to add behavior that’s closely related to the Type they’re extending.
Summary
We’ve just explored Swift extensions by analyzing who should use them, what they are, when they’re appropriate, where to put them, and why they’re useful to your development efforts. As a bonus, how to program an extension was given as a simple example.
If you’ve found Swift extensions to be useful to your development efforts, sound off in the comments below! I’d love to hear how you’re utilizing this feature of Swift.