Protocols
What we know: structs
We can use struct to define our models, they act like blueprints.
struct Car {
let brand: String
let model: String
let year: Int
}
Using that struct, we can then create instances of objects.
let joesCar = Car(brand: "Porsche", model: "911", year: 2025)
let docsCar = Car(brand: "Lamborghini", model: "Aventador", year: 2026)
What we know - methods
We can also add methods to our structs to add functionality.
struct Car {
let brand: String
let model: String
let year: Int
func description() -> String {
return "\(year) \(brand) \(model)"
}
}
let joesCar = Car(brand: "Porsche", model: "911", year: 2025)
print(joesCar.description())
Let’s extend
How can we give this guarantee?
Protocols
A protocol is a contract that describes required properties, methods, or operators, and conformance means a type provides those requirements.
- Just like our
structdefines a blueprint for objects, a protocol defines a blueprint for methods and properties - A protocol can then be adopted by a
struct,class, orenumto provide an actual implementation of those requirements. - Any type that satisfies the requirements of a protocol is said to conform to that protocol.
- With protocols, we can define what a type can do and now different models (
Car,Motorbike) can share behaviour (being describable) through common interfaces
Protocols
- Let’s update our vehicle models…
Swift stops us in our tracks and forces our model to conform.
Pre-defined protocols
We have just defined our own protocol, but there are a bunch of pre-defined, commonly used protocols we can utilise.
CustomStringConvertible- Better debug & display outputEquatable- value comparisonComparable- sortingIdentifiable- creating a stable identityCodable- encoding/decoding for storage and networking
CustomStringConvertible
The CustomStringConvertible protocol lets a type provide a readable description string as a computed property.
Oh - that’s literally what we were just doing! So…
struct Car: CustomStringConvertible {
…
var description: String {
"\(year) \(brand) \(model)"
}
}
let joesCar = Car(brand: "Porsche", model: "911", year: 2025)
print(joesCar)
Our Car struct conforms to this protocol by defining the description property.
Equatable
Comparable
The Comparable Protocol extends Equatable and adds ordering rules, so that values can be sorted.
struct Score: Comparable {
var player: String
var points: Int
static func < (lhs: Score, rhs: Score) -> Bool {
lhs.points < rhs.points
}
}
let scores = [
Score(player: "Mia", points: 25),
Score(player: "Noah", points: 18),
Score(player: "Zoe", points: 30)
]
let sortedScores = scores.sorted()
Here, we conform by adding the < function and defining what makes one score lower than another.
Sets
Sets are a collection of unique values with no guaranteed order.
let tags: Set<String> = ["swift", "protocols", "swift"]
print(tags.count) // 2
print(tags.contains("protocols")) // true
Elements must conform to Hashable.
What does it mean to be Hashable?
Hashable
The Hashable protocol lets Swift generate a consistent hash value from a type’s data so it can be stored in a Set (or used as a dictionary key).
struct Room: Hashable {
let building: String
let number: Int
func hash(into hasher: inout Hasher) {
hasher.combine(building.lowercased())
hasher.combine(number)
}
}
What’s going on here?
Our hash for our Room struct is made from a combination of the building, lowercased, and combined with the number.
Codable and JSONEncoder
The Codable protocol helps us to convert models to and from JSON (JavaScript Object Notation). JSON is a data format commonly used in web contexts, often to transmit data between client and server. It is essentially a list of keys and values.
Identifiable
The Identifiable protocol ensures that types possess a stable, unique identifier (id) so that Swift can efficiently manage items in collections. The id property is commonly implemented using UUID.
struct StudentProfile: Identifiable {
let id: Int
let fullName: String
}
Tasks - SchoolSystem Part 1
- Create a
Studentthat conforms toIdentifiable- Properties:
id,name,age
- Properties:
- Create a
Coursethat conforms toCustomStringConvertible- Properties:
id,title,courseDescription - Description should print a readable summary line
- Properties:
- Create an
Enrolmentthat conforms toCodable- Properties:
studentId,courseId - Encode one submission with
JSONEncoderand decode it withJSONDecoderto make sure it works
- Properties:
Tasks - SchoolSystem Part 2
- Create
ScoreEntrythat conforms toComparable- Properties:
studentId,points - Implement
<using points - Create an array and print entries sorted from lowest to highest
- Properties:
- Update
Enrolmentto conform toHashable- Implement an enrolment hash to be the
studentIdandcourseIdconnected by a full stop. e.g.93CD01EF-5D5D-456A-93AD-FCD7D98F59B3.SWE13 - Build a
SetofEnrolments with duplicates and print the unique count
- Implement an enrolment hash to be the
- Update
ScoreEntryto conform toEquatable.- Implement
==so that ScoreEntrys are equal when the points are equal regardless of the studentId
- Implement
Tasks - SchoolSystem Part 3
- In the main test flow, print:
- Create two
Students- Name: Jules, Age: 16
- Name: Stan, Age: 17
- Create a Course
- Title: 13SWE, Course Description: “Sweet Food in Hospitality”
- Create an
Enrolment: Enrol Stan and Jules in 13SWE- Encode and decode the enrolment. Print the HASH of the decoded enrolment
- Create another
Enrolment: Enrol Stan again in 13SWE using a newEnrolmentobject- Add all enrolment objects to a Set and print out the Set Count
- Create two
ScoreEntry- StudentId: Jules ID, Points: 55
- StudentId: Stans ID, Points: 50
- Add both
ScoreEntryto an array and sort it. Print the results.
- Create a new
Studentcalled Ash, Age 18, and create a ScoreEntry for Ash with 55 points- Compare Ash’s ScoreEntry with Jules’ ScoreEntry. Confirm equality using
==and - print the result
- Compare Ash’s ScoreEntry with Jules’ ScoreEntry. Confirm equality using
- Create two
Tasks - SchoolSystem Extension!
Update your program so that every struct conforms to more than one protocol. Keep the original protocol and add the following:
- Student:
CustomStringConvertible,Codable - Course:
Identifiable,Equatable,Codable - Enrolment:
Identifiable,Equatable,CustomStringConvertible - ScoreEntry:
Comparable,Equatable,Codable
Test each struct with at least two behaviours you’ve added. If you’re feeling adventurous, attempt to encode and decode each of your objects.
Summary
Protocol conformance in Swift lets types participate in powerful shared behaviours.
CustomStringConvertibleimproves output readability,EquatableandComparablesupport logic and sorting,Hashableenables set and dictionary use,Codablesupports data exchange,Identifiablesupports stable identity.
These built-in protocols help your models stay expressive, reusable, and compatible with Swift’s ecosystem.
Review
Use these prompts to check your understanding.
- Explain protocol conformance in one clear sentence,
- describe when to choose
CustomStringConvertible, - compare
EquatableandComparable, - explain why
Hashableis needed forSet, - and name one real project situation where
Codableis essential.