Protocol ve Swiftu — je kontrakt definující sadu požadavků, které musí splnit každý typ, který jej přijme. Protokoly jsou základem protokolově orientovaného programování (POP) — paradigmatu doporučeného Apple pro Swift vedle klasického OOP. Podle Apple Documentation, 2026, struktury, třídy a enum mohou přijímat protokoly, což činí architekturu flexibilní a testovatelnou.
Hlavní body
Protocol — je abstraktní rozhraní, které definuje, co by měl typ umět, ale ne jak to dělá. Ve Swiftu je protokol analogií rozhraní z Javy nebo Go, ale s dalšími možnostmi.
Protokol může vyžadovat:
{ get } nebo { get set }Podle WWDC 2015 Apple představilo Protocol-Oriented Programming jako fundamentální přístup k architektuře Swift aplikací. Na rozdíl od OOP, kde dědičnost tříd vytváří rigidní hierarchie, POP nabízí kompozici protokolů. To poskytuje flexibilitu: jeden typ může odpovídat více protokolům a získávat jejich požadavky a implementace prostřednictvím extensions.
Protocol se deklaruje klíčovým slovem protocol s názvem a tělem.
protocol Drawable {
func draw(context: CGContext)
var boundingBox: CGRect { get }
}
Typ přijímá protokol přes dvojtečku za názvem:
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)
}
}
Jeden typ může přijmout více protokolů oddělených čárkou: struct MyType: ProtocolA, ProtocolB. Kompilátor kontroluje, zda jsou splněny všechny požadavky každého protokolu.
Property requirements se specifikují klíčovým slovem var a specifikátory přístupu { get } nebo { get set }.
protocol UserProtocol {
var name: String { get }
var age: Int { get set }
static var maxAge: Int { get }
mutating func updateName(_ newName: String)
}
Klíčové slovo mutating v protokolu znamená, že metoda může měnit self. Struktury musí takovou metodu implementovat jako mutating, třídy ji mohou vynechat. Method requirements se specifikují s plným podpisem včetně popisků parametrů.
Protocol může dědit jiný protokol a přidávat nové požadavky. To vytváří hierarchii kontraktů bez rigidního propojení s třídami.
protocol Vehicle {
var speed: Double { get set }
func move()
}
protocol Flyable: Vehicle {
var altitude: Double { get set }
func takeOff()
}
Typ přijímající Flyable musí splnit požadavky obou protokolů — jak Vehicle, tak Flyable. Swift podporuje vícenásobnou dědičnost protokolů: protocol A: B, C.
Protocol Composition — mechanismus umožňující určit, že typ musí odpovídat více protokolům současně, bez vytváření nového kombinačního protokolu.
func render(_ item: Drawable & Animatable) {
item.draw(context: ...)
item.animate(duration: 0.3)
}
Composition (&) funguje v parametrech funkcí, proměnných a generických omezeních. Kompilátor kontroluje, zda předaný typ současně vyhovuje všem protokolům. Composition se často používá ve SwiftUI: some View — to je generikum s composition.
Protocol Composition je preferován před vytvářením hierarchie dědičnosti: místo protocol A: B, C lze přímo přijmout B & C. To poskytuje flexibilitu a snižuje provázanost. Composition je obzvláště vhodný v parametrech funkcí a generických omezeních, kde je potřeba dočasně zkombinovat požadavky bez vytváření zprostředkujícího protokolu. To snižuje počet pomocných typů v kódu.
Protocol lze použít jako typ proměnné, parametr funkce nebo prvek kolekce. To se nazývá existential type.
var drawableItem: Drawable
let items: [Drawable] = [Circle(...), Rectangle(...)]
func process(drawables: [any Drawable]) {
for item in drawables {
item.draw(context: ...)
}
}
Klíčové slovo any (Swift 5.6+) explicitně označuje existential. Bez any kompilátor vydá varování. Swift také podporuje some (opaque types) pro skrytí konkrétního typu za protokolem — to je standardní technika ve SwiftUI.
Při práci s protocol vývojáři často dělají několik opakujících se chyb.
Drawable místo <T: Drawable> tam, kde je potřeba konkrétní typAnyObject bez potřeby, což vylučuje struct a enumČasto kladené otázky
Protocol definuje pouze požadavky bez implementace (do protocol extensions). Abstract class může obsahovat implementaci a stav. Ve Swiftu neexistují abstraktní třídy — jejich roli plní protokoly s extensions.
Ano, struktury, třídy a enum — všechny mohou přijímat protokoly. To je základ POP: nejste povinni používat třídy pro organizaci architektury. Struktury s protokoly poskytují sémantiku hodnot a neměnnost.
Associated type (associatedtype) — placeholder pro typ, který si implementující typ určuje sám. Příklad: Collection má associatedtype Element. To je generikum na úrovni protokolu.
Ano, přidejte dědičnost od AnyObject: protocol MyProtocol: AnyObject. Pak pouze třídy mohou přijmout tento protokol. To je užitečné pro weak reference a delegáty.
Použijte is pro kontrolu a as? pro převod: if let drawable = item as? Drawable. To funguje pouze pro protokoly bez associated types.
Shrnutí
&) kombinuje protokoly bez dědičnostiany) a opaque types (some) — dva způsoby práce s protokolyVyvineme mobilní aplikaci na klíč
IT Sectr vytváří aplikace pro iOS a Android pro startupy a podniky od roku 2017. Poradíme vám a navrhneme nejlepší řešení.
Přečtěte si také