Lesson 71Protocols

Protocol Basics

What are Protocols?

Protocols define a blueprint of methods, properties, and other requirements that suit a particular task or functionality. Think of them as contracts that types must fulfill!

Protocol Syntax

protocol ProtocolName {
    var property: Type { get }
    func method()
}

Key Concepts

Property Requirements

Define gettable/settable properties

var name: String { get set }

Method Requirements

Define required methods

func doSomething()

Multiple Conformance

Types can conform to many protocols

struct S: P1, P2, P3

Protocol as Type

Use protocol as parameter/return type

func f(_ p: Protocol)

Class-Only Protocols

Use AnyObject to restrict protocol to class types only:

protocol MyDelegate: AnyObject { }

Required for weak references!

main.swift
// PROTOCOL BASICS
// Protocols define a blueprint of methods, properties, and requirements

// DEFINING A PROTOCOL
protocol Describable {
    var description: String { get }
    func describe()
}

// CONFORMING TO A PROTOCOL
struct Person: Describable {
    var name: String
    var age: Int

    var description: String {
        return "\(name), \(age) years old"
    }

    func describe() {
        print(description)
    }
}

let person = Person(name: "Alice", age: 25)
person.describe()  // Alice, 25 years old

// PROTOCOL WITH METHODS
protocol Greetable {
    func greet() -> String
    func sayGoodbye()
}

struct Employee: Greetable {
    var name: String

    func greet() -> String {
        return "Hello, I'm \(name)"
    }

    func sayGoodbye() {
        print("Goodbye from \(name)!")
    }
}

// PROTOCOL WITH PROPERTY REQUIREMENTS
protocol Named {
    var name: String { get }           // Read-only
    var fullName: String { get set }   // Read-write
}

struct User: Named {
    var name: String           // Can be var (satisfies get)
    var fullName: String       // Must be var (needs set)
}

// MULTIPLE PROTOCOL CONFORMANCE
protocol Identifiable {
    var id: String { get }
}

protocol Printable {
    func printDetails()
}

struct Product: Identifiable, Printable, Describable {
    var id: String
    var name: String
    var price: Double

    var description: String {
        return "\(name) - $\(price)"
    }

    func describe() {
        print(description)
    }

    func printDetails() {
        print("ID: \(id), Name: \(name), Price: $\(price)")
    }
}

// PROTOCOL AS TYPE
func printDescription(_ item: Describable) {
    item.describe()
}

let product = Product(id: "P001", name: "iPhone", price: 999)
printDescription(product)  // iPhone - $999.0
printDescription(person)   // Alice, 25 years old

// ARRAY OF PROTOCOL TYPE
let describables: [Describable] = [person, product]
for item in describables {
    item.describe()
}

// CLASS-ONLY PROTOCOLS
protocol ViewDelegate: AnyObject {
    func didTapButton()
}

class ViewController {
    weak var delegate: ViewDelegate?  // Must be class type

    func buttonTapped() {
        delegate?.didTapButton()
    }
}

Try It Yourself!

Create a Vehicle protocol with properties for speed and passengers, and methods for start() and stop(). Implement it in Car and Bike structs!