Protocol i Swift — vad det är, syntax och möjligheter

Författare: IT Sectr Publicerad: 2026-06-17 Lästid: 6 min

Protocol i Swift — är ett kontrakt som definierar en uppsättning krav som varje typ som accepterar det måste uppfylla. Protokoll ligger till grund för protokollorienterad programmering (POP) — ett paradigm som rekommenderas av Apple för Swift vid sidan av klassisk OOP. Enligt Apple Documentation, 2026 kan strukturer, klasser och enum acceptera protokoll, vilket gör arkitekturen flexibel och testbar.

Huvudpunkter

  • Protocol — kontrakt med krav för strukturer, klasser och enum
  • Requirements omfattar metoder, egenskaper, initierare och subskript
  • Protocol Composition gör det möjligt att kombinera flera protokoll
  • POP — protokollorienterad programmering, alternativ till arv
  • Protocol Extensions lägger till standardimplementeringar för metoder

Vad är Protocol i Swift?

Protocol — är ett abstrakt gränssnitt som definierar vad en typ ska kunna göra, men inte hur det görs. I Swift är protokollet motsvarigheten till gränssnitt från Java eller Go, men med ytterligare möjligheter.

Ett protokoll kan kräva:

  • Metoder för instans och typ (statiska)
  • Egenskaper med specifikation { get } eller { get set }
  • Initierare
  • Subskript
  • Associated types (generik på protokollnivå)

Enligt WWDC 2015 introducerade Apple Protocol-Oriented Programming som ett grundläggande tillvägagångssätt för arkitekturen i Swift-applikationer. Till skillnad från OOP, där klassarv skapar rigida hierarkier, föreslår POP komposition av protokoll. Detta ger flexibilitet: en typ kan motsvara flera protokoll och ta emot deras krav och implementeringar via extensions.

Syntax för deklaration av protokoll

Protocol deklareras med nyckelordet protocol med namn och kropp.

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

Typen accepterar protokollet genom kolon efter namnet:

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)
    }
}

En typ kan acceptera flera protokoll separerade med kommatecken: struct MyType: ProtocolA, ProtocolB. Kompilatorn kontrollerar att alla krav för varje protokoll är uppfyllda.

Krav för metoder och egenskaper

Property requirements specificeras med nyckelordet var och åtkomstspecifikatorer { get } eller { get set }.

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

Nyckelordet mutating i ett protokoll innebär att metoden kan ändra self. Strukturer måste implementera en sådan metod som mutating, klasser kan utelämna det. Method requirements specificeras med full signatur inklusive parametereitketter.

Nedärvning av protokoll

Protocol kan ärva ett annat protokoll och lägga till nya krav. Detta skapar en hierarki av kontrakt utan rigid koppling till klasser.

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

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

Typen som accepterar Flyable måste uppfylla kraven för båda protokollen — både Vehicle och Flyable. Swift stöder multipel nedärvning av protokoll: protocol A: B, C.

Protocol Composition

Protocol Composition — en mekanism som gör det möjligt att specificera att en typ måste motsvara flera protokoll samtidigt, utan att skapa ett nytt kombinationsprotokoll.

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

Composition (&) fungerar i funktionsparametrar, variabler och generiska begränsningar. Kompilatorn kontrollerar att den skickade typen samtidigt uppfyller alla protokoll. Composition används ofta i SwiftUI: some View — är en generisk med composition.

Protocol Composition är att föredra framför att skapa en arvshierarki: istället för protocol A: B, C kan man direkt acceptera B & C. Detta ger flexibilitet och minskar koppling. Composition är särskilt bekvämt i funktionsparametrar och generiska begränsningar, där man tillfälligt behöver kombinera krav utan att skapa ett mellanliggande protokoll. Detta minskar antalet hjälptyper i koden.

Protocol som typ

Protocol kan användas som typ för variabel, funktionsparameter eller samlingselement. Detta kallas existential type.

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

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

Nyckelordet any (Swift 5.6+) anger explicit existential. Utan any ger kompilatorn en varning. Swift stöder också some (opaque types) för att dölja den konkreta typen bakom ett protokoll — detta är standardtekniken i SwiftUI.

Vanliga fel med protokoll

Vid arbete med protocol gör utvecklare ofta flera återkommande misstag.

  • Glömt mutating — metoden i protokollet är markerad som mutating, men strukturen implementerar den utan nyckelordet
  • Protocol as type istället för generic — användning av Drawable istället för <T: Drawable> där en konkret typ behövs
  • Circular protocol reference — protokoll som refererar till sig själv via associated type, utan korrekt lösning
  • Class-only protocol — användning av AnyObject utan behov, vilket utesluter struct och enum

Vanliga frågor

Vad är skillnaden mellan protocol och abstract class?

Protocol definierar endast krav utan implementering (fram till protocol extensions). Abstract class kan innehålla implementering och tillstånd. I Swift finns inga abstrakta klasser — deras roll spelas av protokoll med extensions.

Kan en struct acceptera protocol?

Ja, strukturer, klasser och enum — alla kan acceptera protokoll. Detta är grunden för POP: du är inte tvungen att använda klasser för att organisera arkitekturen. Strukturer med protokoll ger värdessemantik och oföränderlighet.

Vad är associated type i ett protokoll?

Associated type (associatedtype) — en platshållare för den typ som den implementerande typen själv bestämmer. Exempel: Collection har associatedtype Element. Detta är en generisk på protokollnivå.

Kan ett protokoll begränsas till endast klasser?

Ja, lägg till nedärvning från AnyObject: protocol MyProtocol: AnyObject. Då kan endast klasser acceptera detta protokoll. Detta är användbart för weak-referenser och delegater.

Hur kontrollerar man protokollöverensstämmelse vid körning?

Använd is för kontroll och as? för omvandling: if let drawable = item as? Drawable. Detta fungerar endast för protokoll utan associated types.

Sammanfattning

  • Protocol — kontrakt för metoder, egenskaper, initierare och subskript
  • Class, struct, enum — alla typer kan acceptera protokoll
  • Nedärvning av protokoll skapar kontraktshierarki utan rigid koppling
  • Protocol Composition (&) kombinerar protokoll utan nedärvning
  • Existential types (any) och opaque types (some) — två sätt att arbeta med protokoll
  • POP rekommenderat av Apple som alternativ till klassisk klassarv
  • Protocol Extensions gör det möjligt att lägga till standardimplementeringar

Vi utvecklar en mobil applikation nyckelfärdigt

IT Sectr skapar iOS- och Android-applikationer för startups och företag sedan 2017. Vi ger dig råd och föreslår den bästa lösningen.

Diskutera projektet

Läs också