Protocol in Swift — What It Is, Syntax and Capabilities

Author: IT Sectr Published: 2026-06-17 Reading time: 6 min

Protocol in Swift is a contract that defines a set of requirements that any adopting type must satisfy. Protocols are the foundation of Protocol-Oriented Programming (POP) — a paradigm recommended by Apple for Swift alongside classical OOP. According to Apple Documentation, 2026, structures, classes, and enums can adopt protocols, making the architecture flexible and testable.

Key Takeaways

  • Protocol — a contract with requirements for structures, classes, and enums
  • Requirements include methods, properties, initializers, and subscripts
  • Protocol Composition allows combining multiple protocols
  • POP — Protocol-Oriented Programming, an alternative to inheritance
  • Protocol Extensions add default implementations for methods

What Is a Protocol in Swift?

Protocol is an abstract interface that defines what a type must be able to do, but not how it does it. In Swift, a protocol is analogous to interfaces in Java or Go, but with additional capabilities.

A protocol can require:

  • Instance and type methods (static)
  • Properties with { get } or { get set } specifiers
  • Initializers
  • Subscripts
  • Associated types (generics at the protocol level)

According to WWDC 2015, Apple introduced Protocol-Oriented Programming as a fundamental approach to Swift application architecture. Unlike OOP, where class inheritance creates rigid hierarchies, POP offers protocol composition. This provides flexibility: a single type can conform to multiple protocols, gaining their requirements and implementations through extensions.

Protocol Declaration Syntax

Protocol is declared with the protocol keyword, a name, and a body.

swift
protocol Drawable {
    func draw(context: CGContext)
    var boundingBox: CGRect { get }
}

A type adopts a protocol using a colon after its name:

swift
struct Circle: Drawable {
    let center: CGPoint
    let radius: CGFloat

    func draw(context: CGContext) {
        context.addArc(center: center, radius: radius, ...)
    }

    var boundingBox: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
}

A single type can adopt multiple protocols separated by commas: struct MyType: ProtocolA, ProtocolB. The compiler verifies that all requirements of each protocol are fulfilled.

Property and Method Requirements

Property requirements are declared with the var keyword and access specifiers { get } or { get set }.

swift
protocol UserProtocol {
    var name: String { get }
    var age: Int { get set }
    static var maxAge: Int { get }
    mutating func updateName(_ newName: String)
}

The mutating keyword in a protocol indicates that the method may modify self. Structures must implement such a method as mutating, while classes may omit it. Method requirements are declared with a full signature, including parameter labels.

Protocol Inheritance

Protocol can inherit another protocol, adding new requirements. This creates a hierarchy of contracts without rigid class coupling.

swift
protocol Vehicle {
    var speed: Double { get set }
    func move()
}

protocol Flyable: Vehicle {
    var altitude: Double { get set }
    func takeOff()
}

A type adopting Flyable must fulfill the requirements of both protocols — Vehicle and Flyable. Swift supports multiple protocol inheritance: protocol A: B, C.

Protocol Composition

Protocol Composition is a mechanism that allows specifying that a type must conform to multiple protocols simultaneously, without creating a new combined protocol.

swift
func render(_ item: Drawable & Animatable) {
    item.draw(context: ...)
    item.animate(duration: 0.3)
}

Composition (&) works in function parameters, variables, and generic constraints. The compiler verifies that the passed type simultaneously satisfies all protocols. Composition is widely used in SwiftUI: some View is a generic with composition.

Protocol Composition is preferable to creating an inheritance hierarchy: instead of protocol A: B, C, you can adopt B & C directly. This provides flexibility and reduces coupling. Composition is especially useful in function parameters and generic constraints where you need to temporarily combine requirements without creating an intermediate protocol. This reduces the number of auxiliary types in your code.

Protocol as a Type

Protocol can be used as a type for a variable, function parameter, or collection element. This is called an existential type.

swift
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]

func process(drawables: [any Drawable]) {
    for item in drawables {
        item.draw(context: ...)
    }
}

The any keyword (Swift 5.6+) explicitly marks an existential. Without any, the compiler issues a warning. Swift also supports some (opaque types) for hiding the concrete type behind a protocol — this is a standard approach in SwiftUI.

Common Protocol Mistakes

When working with protocols, developers often make several recurring mistakes.

  • Forgotten mutating — a method is marked as mutating in the protocol, but a structure implements it without the keyword
  • Protocol as type instead of generic — using Drawable instead of <T: Drawable> where a concrete type is needed
  • Circular protocol reference — a protocol referencing itself through an associated type without proper resolution
  • Class-only protocol — using AnyObject unnecessarily, which excludes struct and enum

Frequently Asked Questions

How is a protocol different from an abstract class?

Protocol defines only requirements without implementation (until protocol extensions). An abstract class can contain implementation and state. Swift has no abstract classes — their role is fulfilled by protocols with extensions.

Can a struct adopt a protocol?

Yes, structures, classes, and enums can all adopt protocols. This is the foundation of POP: you don’t have to use classes to organize architecture. Structures with protocols provide value semantics and immutability.

What is an associated type in a protocol?

Associated type (associatedtype) is a placeholder for a type that the implementing type determines itself. Example: Collection has associatedtype Element. This is a generic at the protocol level.

Can I restrict a protocol to classes only?

Yes, add inheritance from AnyObject: protocol MyProtocol: AnyObject. Then only classes can adopt this protocol. This is useful for weak references and delegates.

How do I check protocol conformance at runtime?

Use is for checking and as? for casting: if let drawable = item as? Drawable. This only works for protocols without associated types.

Summary

  • Protocol — a contract for methods, properties, initializers, and subscripts
  • Class, struct, enum — all types can adopt protocols
  • Inheritance of protocols creates a hierarchy of contracts without tight coupling
  • Protocol Composition (&) combines protocols without inheritance
  • Existential types (any) and opaque types (some) — two ways to work with protocols
  • POP is recommended by Apple as an alternative to classical class inheritance
  • Protocol Extensions allow adding default implementations

We will develop a mobile application turnkey

IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.

Discuss the project

Read also