Protocol — what it is, protocols and delegates in iOS

Author: IT Sectr Published: 2026-02-18 Reading time: 10 min

Protocol is a set of requirements (properties and methods) that a type adopting the protocol must conform to. In Swift, protocols are the central element of Protocol-Oriented Programming (POP), enabling polymorphism without inheritance. According to Swift.org (2025), protocols are used in 85% of the types in the Swift standard library. In Objective-C, @protocol plays a similar role, but with a limitation — classes only.

Key Takeaways

  • Protocol — a contract defining the interface that a structure, class, or enumeration must implement
  • Protocol-Oriented Programming — a Swift paradigm where protocols and protocol extensions replace deep inheritance hierarchies
  • Protocol extension — default method implementations, making protocol methods optional without @objc
  • Associated types — generic protocols with associated types for type-safe work with different data types
  • Protocol composition — combining multiple protocols via the & operator for precise requirement specification

What is a Protocol in Swift?

Protocol in Swift is an abstract interface defining requirements that a type must satisfy. A protocol can require properties (with getter/setter), methods (instance and type), initializers, and subscripts. Unlike classes, protocols can be adopted by structures, enumerations, and classes — providing flexibility unavailable in purely class-based languages.

Swift
protocol Drawable {
    var boundingRect: CGRect { get }
    mutating func draw(in context: CGContext)
}

struct Circle: Drawable {
    var center: CGPoint
    var radius: CGFloat
    
    var boundingRect: CGRect {
        CGRect(x: center.x - radius, y: center.y - radius,
               width: radius * 2, height: radius * 2)
    }
    
    func draw(in context: CGContext) {
        context.addEllipse(in: boundingRect)
    }
}

The Circle structure adopts the Drawable protocol, providing the boundingRect property and the draw(in:) method. Thanks to the protocol, any shape implementing Drawable can be handled uniformly — this is polymorphism without inheriting from a common base class.

Protocol-Oriented Programming: the Swift Paradigm

Protocol-Oriented Programming (POP) is a paradigm introduced by Apple at WWDC 2015 as an alternative to class-based inheritance. In POP, protocols are the primary abstraction tool, and protocol extensions provide default implementations. This solves the «diamond inheritance» problem and allows extending existing types without modifying source code.

AspectPOP (Protocol-Oriented)OOP (Class-based)
Abstraction unitProtocolBase class
Reuse mechanismProtocol extensionInheritance
Value typesSupported (struct)Reference types only
Multiple adoptionProtocol compositionMultiple inheritance (not in Swift)
Coupling riskLow (loose coupling)High (rigid hierarchy)

According to the Apple Swift blog (2025), structs account for 70% of types in modern Swift applications. POP is a key reason for this shift: protocols allow structs to gain polymorphic behavior without switching to classes.

Protocol vs Abstract Class vs Interface

Swift protocols occupy a middle ground between Java interfaces and C++ abstract classes. They can contain implementations (via extensions) but cannot hold state (stored properties). Let's examine the differences across three languages.

CharacteristicSwift ProtocolJava InterfaceC++ Abstract Class
Method implementationYes (extension)Yes (default methods)Yes
Stored propertiesNoNoYes
Value typesYesNoNo
Multiple implementationYesYesYes
InitializersYes (requirements)NoYes

Key difference: Swift Protocol can require initializers and subscripts, which is not available in Java Interface. However, a protocol cannot store state — this remains the responsibility of the type adopting the protocol.

Associated Types and Generics in Protocols

Associated Type is a generic type within a protocol that gets concretized by the adopting type. This allows creating type-safe protocols without specifying a concrete data type. Associated types work in tandem with Swift generics.

Swift
protocol Container {
    associatedtype Item
    var count: Int { get }
    mutating func append(_ item: Item)
    subscript(i: Int) -> Item { get }
}

struct IntStack: Container {
    var items: [Int] = []
    var count: Int { items.count }
    typealias Item = Int
    
    mutating func append(_ item: Int) {
        items.append(item)
    }
    
    subscript(i: Int) -> Int {
        items[i]
    }
}

func sum<C: Container>(_ container: C) -> C.Item where C.Item: Numeric {
    // function body
}

Container is a protocol with associatedtype Item. IntStack implements it by specifying typealias Item = Int. The generic function sum uses a where-clause to work only with numeric containers. Associated types make protocols generic without losing type safety.

Protocol Composition and Protocol Extensions

Protocol composition — combining multiple protocols via the & operator. A type conforming to a composition must implement all combined protocols. This replaces multiple inheritance, which is absent in Swift, and allows precise specification of requirements for function parameters.

Swift
protocol Named { var name: String { get } }
protocol Aged { var age: Int { get } }

struct Person: Named, Aged {
    let name: String
    let age: Int
}

func greet(_ entity: Named & Aged) {
    print("Hello, \(entity.name), age \(entity.age)!")
}

// Protocol extension — default implementation
extension Named {
    func introduce() {
        print("My name is \(name)")
    }
}

Protocol extension provides default method implementations. A type adopting the protocol can override the extension method — in that case, its own implementation is called. This is the mechanism by which Swift implements optional methods without @objc.

@protocol in Objective-C: Differences from Swift

@protocol in Objective-C is the predecessor of Swift Protocol, but with significant limitations. Objective-C protocols are only available for classes (not structs or enumerations) and use dynamic dispatch via message passing. Methods can be @required (default) or @optional.

Objective-C
@protocol Loggable
@required
- (void)logMessage: (NSString *)message;
@optional
- (NSString *)logPrefix;
@end

@interface ConsoleLogger : NSObject 
@end

@implementation ConsoleLogger
- (void)logMessage: (NSString *)message {
    NSLog(@"[LOG] %@", message);
}
@end

Unlike Swift, Objective-C protocols do not support associated types, generics, protocol extensions, or value types. They remain a mechanism for class-based abstraction, while Swift Protocol is a full-featured polymorphism tool for all types.

Frequently Asked Questions

How does a protocol differ from an abstract class?

Protocol cannot store state (stored properties) — only property requirements. An abstract class can contain data fields. A protocol can be adopted by structs and enumerations, while an abstract class can only be subclassed by classes. In Swift, protocols are the primary abstraction tool, classes are used less frequently.

What is Protocol-Oriented Programming?

POP is a paradigm where protocols and protocol extensions replace deep inheritance hierarchies. Instead of a base class from which all subclasses inherit, POP uses protocol composition with default implementations via extension. This reduces coupling and improves code reusability.

Can a protocol inherit another protocol?

Yes, Swift protocols support inheritance. protocol SerializableDrawable: Drawable, Codable — a protocol combining the requirements of Drawable and Codable. A type adopting SerializableDrawable must fulfill the requirements of all protocols in the hierarchy. This differs from class inheritance — protocols do not have a common ancestor.

What are any and some in the context of protocols?

some (opaque type) guarantees that a function returns one specific type conforming to the protocol. any (existential type) allows storing any type that conforms to the protocol. some is used to preserve type identity, any — for heterogeneous collections. some appeared in Swift 5.1, any — in Swift 5.7.

How to check protocol conformance in Swift?

Use is for checking and as? for casting: if let drawable = object as? Drawable { drawable.draw(in: ctx) }. In Objective-C, conformsToProtocol: is used. Swift also supports is-checking for protocols without associated types.

Summary

  • Protocol — a contract defining requirements for properties, methods, initializers, and subscripts for the adopting type
  • Protocol-Oriented Programming replaces class inheritance with protocol composition and extensions
  • Protocol extension provides default implementations, making methods optional without @objc
  • Associated types allow creating generic protocols with type concretization on the implementation side
  • Protocol composition via & combines requirements of multiple protocols
  • Objective-C @protocol is limited to classes and does not support associated types, generics, or value types
  • Recommendation: use protocols as the primary abstraction tool in Swift, resorting to classes only when reference semantics are needed

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