Labs ICT
โญ Pro Login

Protocols

Defining contracts for types.

3 min read | Swift Tutorial
โญ

Want the full learning experience?

Get structured courses, certificates, projects, and instructor support with LabsICT Pro.

Explore Pro Courses

Protocols in Swift

Protocols are blueprints that define what methods, properties, and other requirements a type must have. They don't provide implementations โ€” they just describe the contract. Any type (struct, class, or enum) can conform to a protocol by implementing its requirements.

protocol Describable {
    func describe() -> String
}

struct Car: Describable {
    var make: String
    var model: String
    
    func describe() -> String {
        return "\(make) \(model)"
    }
}

let myCar = Car(make: "Tesla", model: "Model 3")
print(myCar.describe()) // Tesla Model 3

Protocol Requirements

Protocols can require specific properties and methods. Properties must specify whether they're gettable ({ get }) or gettable and settable ({ get set }). Methods are declared without a body โ€” just the signature.

protocol Vehicle {
    var speed: Double { get set }
    var isRunning: Bool { get }
    func start()
    func stop()
}

struct Bicycle: Vehicle {
    var speed: Double = 0
    var isRunning: Bool = false
    
    mutating func start() {
        isRunning = true
        print("Pedaling!")
    }
    
    mutating func stop() {
        isRunning = false
        speed = 0
        print("Stopped")
    }
}

Protocol Inheritance

Protocols can inherit from other protocols, extending the requirements. A type that conforms to the child protocol must implement all requirements from both the child and parent protocols.

protocol Named {
    var name: String { get }
}

protocol Aged {
    var age: Int { get }
}

protocol Person: Named, Aged {
    func introduce()
}

struct Student: Person {
    var name: String
    var age: Int
    
    func introduce() {
        print("Hi, I'm \(name) and I'm \(age) years old.")
    }
}

let student = Student(name: "Alice", age: 20)
student.introduce() // Hi, I'm Alice and I'm 20 years old.

Protocol Extensions

Protocol extensions let you provide default implementations for protocol requirements. This means conforming types don't have to implement everything from scratch โ€” they get the default behavior for free and can override it if needed.

protocol Greetable {
    var name: String { get }
}

extension Greetable {
    func greet() -> String {
        return "Hello, my name is \(name)!"
    }
}

struct Person: Greetable {
    var name: String
    // No need to implement greet() โ€” the extension provides it
}

let person = Person(name: "Alice")
print(person.greet()) // Hello, my name is Alice!

Standard Protocols

Swift comes with many built-in protocols that provide useful functionality. Equatable lets you compare instances with ==, Comparable lets you sort instances, and Codable lets you encode and decode instances to and from JSON.

struct Score: Comparable {
    let player: String
    let points: Int
    
    static func < (lhs: Score, rhs: Score) -> Bool {
        return lhs.points < rhs.points
    }
}

let scores = [
    Score(player: "Alice", points: 85),
    Score(player: "Bob", points: 92),
    Score(player: "Charlie", points: 78)
]

let sorted = scores.sorted()
for score in sorted {
    print("\(score.player): \(score.points)")
}
// Charlie: 78
// Alice: 85
// Bob: 92

Why Protocols Matter

Protocols are central to Swift's design philosophy. They let you write flexible, reusable code by programming to an interface rather than a concrete type. Protocol-oriented programming (POP) is a powerful paradigm that Swift embraces wholeheartedly.

protocol Drawable {
    func draw()
}

func renderShapes(_ shapes: [Drawable]) {
    for shape in shapes {
        shape.draw()
    }
}

struct Circle: Drawable {
    func draw() { print("Drawing a circle") }
}

struct Square: Drawable {
    func draw() { print("Drawing a square") }
}

let shapes: [Drawable] = [Circle(), Square(), Circle()]
renderShapes(shapes)
// Drawing a circle
// Drawing a square
// Drawing a circle

๐Ÿงช Quick Quiz

What keyword makes a type conform to a protocol?