Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

A protocol defines a strict blueprint of methods, properties, initializers, and associated types required to implement a specific piece of functionality. It acts as an interface contract that classes, structures, and enumerations can adopt. When a type satisfies all the requirements of a protocol, it is said to conform to that protocol.

Protocol Declaration and Conformance

Protocols are declared using the protocol keyword. Types declare conformance by appending the protocol name after the type name, separated by a colon. Multiple protocols are separated by commas.
protocol Displayable {
    // Requirements go here
}

struct User: Displayable, Equatable {
    // Implementation goes here
}

Property Requirements

Protocols can require conforming types to provide specific instance properties or type properties.
  • Properties must always be declared as variables (var), never constants (let).
  • The protocol specifies whether the property must be gettable ({ get }) or both gettable and settable ({ get set }).
  • Type properties are prefixed with the static keyword.
import Foundation

protocol Resource {
    var id: String { get }
    var data: Data { get set }
    static var maxCapacity: Int { get }
}

Method Requirements

Protocols can require specific instance methods and type methods.
  • Method signatures are defined without a body (no curly braces).
  • Default parameters are not allowed in protocol method declarations.
  • Type methods are prefixed with static.
  • If a method modifies the instance of a value type (struct or enum), it must be prefixed with the mutating keyword. Classes conforming to the protocol ignore the mutating keyword.
protocol StateMachine {
    func transition(to state: Int) throws
    static func reset()
    mutating func increment()
}

Initializer Requirements

Protocols can require specific initializers. When a class conforms to a protocol with an initializer requirement, the implementation must be marked with the required modifier to ensure all subclasses also provide the initializer. (Structs do not need the required modifier).
protocol Deserializable {
    init(dictionary: [String: Any])
}

class Model: Deserializable {
    required init(dictionary: [String: Any]) {
        // Implementation
    }
}

Associated Types

Protocols cannot use standard generic type parameters (e.g., <T>). Instead, they use associated types to define placeholders for types used within the protocol’s requirements. The conforming type determines the actual concrete type.
protocol Container {
    associatedtype Item
    mutating func append(_ item: Item)
    var count: Int { get }
}

struct IntStack: Container {
    typealias Item = Int // Optional: Swift can usually infer this
    
    var count: Int { 
        return 0 // implementation
    }
    
    mutating func append(_ item: Int) { 
        // implementation
    }
}

Protocol Inheritance

A protocol can inherit requirements from one or more other protocols. The syntax mirrors class inheritance. Conforming types must satisfy the requirements of the inherited protocols as well as the new protocol.
protocol Persistable: Displayable, Deserializable {
    func save()
}

Class-Only Protocols

To restrict protocol conformance exclusively to reference types (classes), the protocol must inherit from AnyObject. This is commonly used to prevent strong reference cycles by allowing protocol-typed properties to be declared as weak.
protocol Delegate: AnyObject {
    func didCompleteTask()
}

Protocol Composition

You can require a type to conform to multiple protocols simultaneously using the & operator. This creates an existential type representing the intersection of the specified protocols. In modern Swift, existential types must be explicitly marked with the any keyword (or some for opaque types).
func process(data: any Displayable & Deserializable) {
    // data must conform to both protocols
}

Protocol Extensions

Protocols can be extended to provide method and property implementations. This allows you to define default behavior for protocol requirements or add new functionality to all conforming types without modifying the conforming types themselves.
protocol Loggable {
    var logMessage: String { get }
    func printLog()
}

extension Loggable {
    // Default implementation
    func printLog() {
        print(logMessage)
    }
}
Master Swift with Deep Grasping Methodology!Learn More