Swift Protocols

iOS
Swift protocols act as blueprints for classes, structs, and enums, enabling them to adopt predefined properties and methods. Unlike interfaces in some other languages, Swift protocols can declare properties and permit a single type to conform to multiple protocols. This flexibility supports a range of use cases, including dependency injection and code testability.

A Swift Protocol is Swift's version of an Interface in object-oriented programming (OOP). If you're new to OOP, think of an interface as a blueprint that any class, struct, or enum adopting it must follow. For example, imagine a Vehicle interface that declares a function startEngine(). In Swift, any type conforming to the Vehicle protocol must implement startEngine(). This is known as Protocol Conformance.

// Swift code example
protocol Vehicle {
  func startEngine()
}

struct Car: Vehicle {
  func startEngine() {
    // Implementation for car
  }
}

When compared to interfaces in languages like Java, Swift Protocols have two key distinctions:

  • You can declare properties, either read-only or mutable.
  • You can have a single type conform to multiple protocols.
These features make Swift Protocols versatile for various use cases.

Why use protocols?

Protocols help abstract your code. Here are some practical applications:

  • Swift protocols establish contracts between different components without exposing unnecessary details. For instance, a vehicle's user doesn't need to know how an ATV or spaceship starts its engine—just that they can call startEngine().
  • Composite protocol conformance lets you combine multiple protocols into a single type. Imagine you have a biology app with Flyable and Mammal protocols. You would make Bat type would conform Flyable and Mammal. Cow and Cat would conform to Mammal. Hummingbird and Toucan would conform to Flyable.
    // Swift code example
    protocol Flyable {}
    protocol Mammal {}
    
    struct Bat: Flyable, Mammal {}
  • Protocols facilitate dependency injection (DI) and make components testable. For example, you can define a UserDefaults protocol and use it consistently, making it easier to swap out instances for testing.
    // Swift code example
    protocol UserDefaultsProtocol {
      // Method declarations
    }
  • Protocols offer a form of inheritance for structs and enums, not just classes. This is resource-efficient, as classes can be memory-intensive.
  • Using Swift protocols ensures compile-time safety. The compiler will enforce the correct implementation across all conforming types, reducing developer errors and aiding refactoring.

While protocols can be very helpful, they can can negatively impact performance. We've written in the past about the cost of protocol conformance + how they can be sped up.

Sign up for our newsletter 🛸

Never miss a post or product update



2024 © Emerge Tools, Inc. All rights reserved.