SWIFT

Swift Protocol: Syntax, Usage, and Examples

A Swift protocol defines a blueprint of methods, properties, and other requirements that classes, structures, and enumerations must adopt. Protocols let you define shared functionality without requiring inheritance, making them a key part of protocol-oriented programming in Swift.

How to Use Protocols in Swift

To define a protocol, use the protocol keyword, then list the required properties and methods. Any type that conforms to the protocol must implement these requirements.

protocol Greetable {
    var name: String { get }
    func greet()
}

struct Person: Greetable {
    var name: String

    func greet() {
        print("Hello, my name is \(name).")
    }
}

let john = Person(name: "John")
john.greet() // Output: Hello, my name is John.

Here, Greetable is a Swift protocol that requires a name property and a greet method. The Person struct conforms to the protocol by implementing both.

Protocol Properties

Protocols define protocol properties in Swift that conforming types must provide. These can be read-only ({ get }) or read-write ({ get set }).

protocol Vehicle {
    var speed: Int { get set }
    var capacity: Int { get }
}

Protocol Methods

Protocols can define methods without providing an implementation. Any type conforming to the protocol must implement these methods.

protocol Drivable {
    func start()
    func stop()
}

class Car: Drivable {
    func start() {
        print("Car is starting...")
    }

    func stop() {
        print("Car is stopping...")
    }
}

When to Use Protocols in Swift

Standardizing Behavior

Protocols help define a standard behavior across multiple types without forcing them into a class hierarchy.

protocol Flyable {
    func fly()
}

struct Bird: Flyable {
    func fly() {
        print("The bird is flying.")
    }
}

struct Plane: Flyable {
    func fly() {
        print("The plane is flying.")
    }
}

Creating Flexible Code

You can use protocol-oriented programming in Swift to make your code more flexible by defining shared behavior that multiple unrelated types can adopt.

protocol Storable {
    func save()
}

class Document: Storable {
    func save() {
        print("Saving document...")
    }
}

class Image: Storable {
    func save() {
        print("Saving image...")
    }
}

Supporting Delegation

Protocols are commonly used for delegation, allowing one object to pass responsibility to another.

protocol DownloadDelegate {
    func didFinishDownloading()
}

class Downloader {
    var delegate: DownloadDelegate?

    func download() {
        print("Downloading...")
        delegate?.didFinishDownloading()
    }
}

class ViewController: DownloadDelegate {
    func didFinishDownloading() {
        print("Download complete!")
    }
}

let vc = ViewController()
let downloader = Downloader()
downloader.delegate = vc
downloader.download()
// Output:
// Downloading...
// Download complete!

Examples of Protocols in Swift

Using a Protocol with an Array

You can store different types in an array as long as they conform to the same protocol.

protocol Animal {
    func makeSound()
}

struct Dog: Animal {
    func makeSound() {
        print("Woof!")
    }
}

struct Cat: Animal {
    func makeSound() {
        print("Meow!")
    }
}

let animals: [Animal] = [Dog(), Cat()]
animals.forEach { $0.makeSound() }
// Output:
// Woof!
// Meow!

Extending Protocols

A Swift protocol extension allows you to add default implementations for protocol methods.

protocol Identifiable {
    var id: String { get }
}

extension Identifiable {
    func identify() {
        print("My ID is \(id).")
    }
}

struct User: Identifiable {
    var id: String
}

let user = User(id: "123")
user.identify() // Output: My ID is 123.

Using Generics with Protocols

A Swift generic protocol allows you to define flexible and reusable code that works with multiple types.

protocol Storage {
    associatedtype Item
    func store(_ item: Item)
}

class Box<T>: Storage {
    typealias Item = T
    func store(_ item: T) {
        print("Storing \(item)")
    }
}

let intBox = Box<Int>()
intBox.store(42) // Output: Storing 42

Protocol Inheritance

A protocol can inherit from one or more protocols using a comma-separated list.

protocol Movable {
    func move()
}

protocol Stoppable {
    func stop()
}

protocol Vehicle: Movable, Stoppable {}

class Bicycle: Vehicle {
    func move() {
        print("Bicycle is moving.")
    }

    func stop() {
        print("Bicycle is stopping.")
    }
}

let bike = Bicycle()
bike.move() // Output: Bicycle is moving.
bike.stop() // Output: Bicycle is stopping.

Learn More About Protocols in Swift

Class-Only Protocols

You can restrict a protocol to class-only types using AnyObject.

protocol ViewControllerDelegate: AnyObject {
    func didUpdate()
}

Optional Protocol Methods

Swift doesn't support optional protocol methods directly, but you can work around this using @objc and optional.

@objc protocol OptionalProtocol {
    @objc optional func optionalMethod()
}

Protocol vs. Class

  • Protocols allow multiple types to share behavior without inheritance.
  • Classes enforce a strict hierarchy where child classes inherit from a parent.
  • Use protocols when defining behavior that multiple unrelated types should conform to.
  • Use classes when modeling relationships where objects need shared state and behavior.

Protocol-Oriented Programming vs. Object-Oriented Programming

  • Object-Oriented Programming (OOP) relies on classes and inheritance.
  • Protocol-Oriented Programming (POP) promotes composition over inheritance, leading to more modular and testable code.

Using Protocols in Real-World Projects

Protocols are widely used in SwiftUI, UIKit, and networking. You often see them in delegate patterns, custom UI components, and dependency injection.

Example: Networking with a Protocol

protocol NetworkService {
    func fetchData(from url: String)
}

class APIClient: NetworkService {
    func fetchData(from url: String) {
        print("Fetching data from \(url)")
    }
}

let apiClient: NetworkService = APIClient()
apiClient.fetchData(from: "https://example.com")
// Output: Fetching data from https://example.com

Best Practices for Using Protocols in Swift

  • Use protocols instead of inheritance when possible. They make your code more flexible and reusable.
  • Define small, focused protocols. Avoid protocols with too many responsibilities.
  • Use protocol extensions to provide default implementations.
  • Avoid forcing class inheritance unless necessary. Use protocol-oriented programming when structuring your app.
  • Prefer composition over inheritance. Instead of creating deep class hierarchies, break functionality into separate protocols.
Learn to Code in Swift for Free
Start learning now
button icon
To advance beyond this tutorial and learn Swift by doing, try the interactive experience of Mimo. Whether you're starting from scratch or brushing up your coding skills, Mimo helps you take your coding journey above and beyond.

Sign up or download Mimo from the App Store or Google Play to enhance your programming skills and prepare for a career in tech.

You can code, too.

© 2025 Mimo GmbH