1. April 2018

Protokolle in Swift

Mit einem Protokoll kann in Swift ein Schnittstellenkontrakt definiert werden. Das Protokoll gibt dabei an, welche Methoden vorhanden sein müssen. Zum Beispiel:

protocol Account {
    func withdraw(amount : Int)
    func deposit(amount : Int)
}

Auch Eigenschaften können dabei vom Protokoll gefordert werden - dabei besteht die Möglichkeit anzugeben, ob diese nur gelesen oder auch verändert werden dürfen:

protocol Account {
    var balance : Int { get set }

    func withdraw(amount : Int)
    func deposit(amount : Int)
}

Klassen, die die Anforderungen des Protokolls erfüllen, können als konform zu dem Protokoll deklariert werden:

class CheckingAccount : Account {
    // ...
}

Tipp: Die zu implementierenden Methoden können von Xcode automatisch erstellt werden:

Protokollmethoden von Xcode anlegen lassen

Beispielsweise wäre folgende Implementierung konform zu dem Account-Protokoll:

class CheckingAccount : Account {
    var balance = 0
    
    func withdraw(amount : Int) {
        balance -= amount
    }
    
    func deposit(amount : Int) {
        balance += amount
    }
}

Bei der Verwendung des Protokoll-Typs wird die konkrete Implementierung hinter der Schnittstelle „versteckt“. So akzeptiert beispielsweise eine Funktion, die ein Objekt vom Typ Account übergeben bekommt, jedes Objekt, das konform zu dem Protokoll ist:

func transfer(amount : Int, fromAccount : Account, toAccount : Account) {
    fromAccount.withdraw(amount: amount)
    toAccount.deposit(amount: amount)
}

Um welche Klasse es sich dabei konkret handelt, spielt für die Funktion keine Rolle:

let account1 : Account = CheckingAccount()
let account2 : Account = CheckingAccount()
transfer(amount: 10, fromAccount: account1, toAccount: account2)

Tutorial 1: UIApplicationDelegate-Protokoll in UIKit

  1. Laden Sie den Start-Stand von dem Flashcards-Beispielprojekt: Flashcards.zip.

  2. Machen Sie sich mit dem UIApplicationDelegate-Protokoll vertraut: das AppDelegate wird beim Start der App automatisch bei der UIApplication als Delegate registriert.

  3. Ergänzen Sie print-Statements in den AppDelegate-Methoden wie application(didFinishLaunchingWithOptions:) und applicationWillResignActive usw. und beobachten Sie die Ausgabe dieser Ereignisse bei der Interaktion mit der App im Simulator:

    class AppDelegate: UIResponder, UIApplicationDelegate {
    
        var window: UIWindow?
    
        func application(_ application: UIApplication, didFinishLaunchingWithOptions
              launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
            // Override point for customization after application launch.
            print("application(didFinishLaunchingWithOptions:)")
            return true
        }
    
        func applicationWillResignActive(_ application: UIApplication) {
            print("applicationWillResignActive")
        }
    
        // ...
    
    }

Tutorial 2: Protokoll für Backend-Kommunikation einführen

In den folgenden Kapiteln werden die Daten via https in einem JSON-Datenformat geladen. Der folgende Schritt schafft in einem ersten vorbereitenden Schritt Datenstrukturen für diesen Vorgang.

  1. Legen Sie eine neue Gruppe Backend an und erstellen Sie hier eine neue Quelltextdatei FlashcardsAPIClient.swift an.

  2. Definieren Sie ein Protokoll FlashcardsAPIClient für die Kommunikation mit der Online-Schnittstelle und definieren Sie eine Eigenschaft mit einer Liste von ladbaren Kartenstapeln und einer Methode um einen Kartenstapel herunterzuladen:

    protocol FlashcardsAPIClient {
    
        var allSets : [String] { get }
        func downloadSet(id: Int)
    
    }

    Hinweis: Diese Schnittstelle ist aktuell bewusst simpelstmöglich definiert und wird später angepasst und erweitert.

  3. Erstellen Sie eine einfache Beispielimplementierung DemoFlashcardsAPIClient:

    class DemoFlashcardsAPIClient : FlashcardsAPIClient {
    
        var allSets: [String] = ["German/English: Common verbs", "Spanish/English: Animals"]
    
        func downloadSet(id: Int) {
            fatalError("Noch nicht implementiert")
        }
    
    }
  4. Bauen Sie das Projekt und committen Sie Ihre Änderungen als „11.2. Protokoll für Backend-Kommunikation“.