Chapter 9: Protocols and Extensions in Swift: Adding Flexibility and Functionality
This post is part of a series about programming with Swift to build iOS apps. Be sure to check out the other posts in the series for a complete journey into mastering iOS development.
In Swift, protocols and extensions are powerful tools for building flexible, reusable, and well-organized code. They allow you to define shared behaviors and extend existing types with new functionality—without modifying their original definitions.
In this post, we’ll cover:
Protocols: What they are and how to use them.
Extensions: Adding functionality to existing types.
A practical SwiftUI example demonstrating protocols and extensions.
1. What is a Protocol?
A protocol defines a blueprint of methods, properties, or other requirements that a class, struct, or enum must conform to. Think of it as a contract: if a type adopts a protocol, it agrees to implement the specified behavior.
Defining and Adopting a Protocol
Here’s how to define and use a protocol:
protocol Describable {
var description: String { get }
func describe()
}
struct User: Describable {
var name: String
var age: Int
var description: String {
return "\(name), \(age) years old"
}
func describe() {
print(description)
}
}
let user = User(name: "Mihai", age: 39)
user.describe() // Output: Mihai, 39 years old2. Using Protocols for Shared Behavior
Protocols are particularly useful when multiple types share similar behavior:
protocol Payable {
func calculateSalary() -> Double
}
struct Employee: Payable {
var hourlyRate: Double
var hoursWorked: Double
func calculateSalary() -> Double {
return hourlyRate * hoursWorked
}
}
struct Freelancer: Payable {
var projectRate: Double
func calculateSalary() -> Double {
return projectRate
}
}
let employee = Employee(hourlyRate: 20, hoursWorked: 40)
let freelancer = Freelancer(projectRate: 1000)
print(employee.calculateSalary()) // Output: 800
print(freelancer.calculateSalary()) // Output: 10003. What is an Extension?
An extension allows you to add new functionality to an existing type—whether it’s a type you’ve defined or one from the Swift standard library.
Adding Methods with Extensions
Here’s an example of extending the String type:
extension String {
func reversedString() -> String {
return String(self.reversed())
}
}
let name = "Mihai"
print(name.reversedString()) // Output: iahiMAdding Default Implementations to Protocols
Extensions can also provide default implementations for protocol methods:
protocol Greeter {
func greet()
}
extension Greeter {
func greet() {
print("Hello!")
}
}
struct FriendlyPerson: Greeter {}
let person = FriendlyPerson()
person.greet() // Output: Hello!4. From Playground to SwiftUI
Let’s see how protocols and extensions can be applied in a SwiftUI project by creating a dedicated Chapter9View.
Step 1: Create Chapter9View.swift
Add a new Swift file named Chapter9View.swift to your project, and add the following code:
import SwiftUI
protocol PriorityDisplayable {
var priorityColor: Color { get }
}
enum TaskPriority: String, PriorityDisplayable {
case high = "High"
case medium = "Medium"
case low = "Low"
var priorityColor: Color {
switch self {
case .high:
return .red
case .medium:
return .orange
case .low:
return .green
}
}
}
struct Task {
let title: String
let priority: TaskPriority
}
struct Chapter9View: View {
@State private var tasks: [Task] = [
Task(title: "Finish project", priority: .high),
Task(title: "Buy groceries", priority: .medium),
Task(title: "Go for a walk", priority: .low)
]
var body: some View {
List(tasks, id: \.title) { task in
HStack {
Text(task.title)
Spacer()
Text(task.priority.rawValue)
.foregroundColor(task.priority.priorityColor)
}
}
.navigationTitle("Tasks")
}
}Step 2: Update ContentView.swift
Modify ContentView to load Chapter9View:
import SwiftUI
struct ContentView: View {
var body: some View {
Chapter9View()
}
}
#Preview {
ContentView()
}Explanation of the Code
Protocol Usage:
PriorityDisplayableensures that any type adopting it provides apriorityColor.The
TaskPriorityenum conforms to the protocol and implementspriorityColor.
Extension Benefits:
The protocol extension could provide a default implementation for
priorityColor, if applicable.The reusable logic for priority display enhances readability and maintainability.
Challenges
Add a method in a protocol to calculate the urgency of a task and display it alongside the priority.
Extend the
Arraytype to include a method that filters tasks by priority.
What’s Next?
With protocols and extensions, you’ve unlocked tools that make your code more modular and reusable. In the next post, we’ll start exploring SwiftUI fundamentals, laying the groundwork for building custom views and creating a dynamic user interface.
Let’s keep building!

