ViewController

class ViewController: UIViewController, UITextFieldDelegate

Einzige ViewController-Klasse der App. Die Klasse enthält mehrere Methoden, die alle dieselbe Berechnung durchführen, aber die Fehlerbehandlung auf unterschiedliche Weisen implementieren; für jede dieser Berechnungs-Methoden gibt es einen Button auf der Oberfläche.

  • String-Konstante mit Temperatur-Einheit °C (Grad Celsius), zum Anhängen an Anzeige-Texte.

    Declaration

    Swift

    let gradCelsiusString = "°C"
  • Formatierer-Objekt für den Ergebniswert (Liter kaltes Wasser), für Darstellung mit immer genau einer Nachkommastelle. Wird mit einem Closure initialisiert.

    Declaration

    Swift

    let ergebnisWertFormatierer:NumberFormatter =
  • UI-Element zum Einstellen der Heißwassertemperatur; Bereich: 0°C bis 100°C, jeweils einschließlich.

    Declaration

    Swift

    @IBOutlet weak var sliderTempHeissesWasser: UISlider!
  • UI-Element zum Einstellen der Kaltwassertemperatur; Bereich: 0°C bis 100°C, jeweils einschließlich.

    Declaration

    Swift

    @IBOutlet weak var sliderTempKaltesWasser : UISlider!
  • UI-Element zum Einstellen der Zieltemperatur (gewünschte Misch-Temperatur); Bereich: 0°C bis 100°C, jeweils einschließlich.

    Declaration

    Swift

    @IBOutlet weak var sliderTempZiel         : UISlider!
  • UI-Element zur Anzeige der mit zugehörigem Slider aktuell eingestellten Heißwassertemperatur.

    Declaration

    Swift

    @IBOutlet weak var labelTempHeissesWasser:  UILabel!
  • UI-Element zur Anzeige der mit zugehörigem Slider aktuell eingestellten Kaltwassertemperatur.

    Declaration

    Swift

    @IBOutlet weak var labelTempKaltesWasser :  UILabel!
  • UI-Element zur Anzeige der mit zugehörigem Slider aktuell eingestellten Zieltemperatur (Mischtemperatur).

    Declaration

    Swift

    @IBOutlet weak var labelTempZiel         :  UILabel!
  • Textfeld zur Eingabe der Heißwassermenge; wird in Methode viewDidLoad() so konfiguriert, dass nur Ganzzahlwerte in dieses Feld eingegeben werden können. Die in diesem Feld eingegebene Wassermenge kann mit der Methode getHeisswasserLiter() ausgelesen werden.

    Declaration

    Swift

    @IBOutlet weak var textFieldMengeHeissesWasser: UITextField!
  • Event-Handler-Methode für Änderung Kaltwasser-Temperatur mit Slider-Element.

    Declaration

    Swift

    @IBAction func onSliderTempKaltWasserChanged(_ sender: UISlider)
  • Event-Handler-Methode für Änderung Heißwasser-Temperatur mit Slider-Element.

    Declaration

    Swift

    @IBAction func onSliderTempHeissesWasserChanged(_ sender: UISlider)
  • Event-Handler-Methode für Änderung Ziel-Temperatur (Misch-Temperatur) mit Slider-Element.

    Declaration

    Swift

    @IBAction func onSliderTempZielTempChanged(_ sender: UISlider)
  • Event-Handler-Methode für Button Catch 1, führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitCatch1(_ sender: UIButton)
  • Event-Handler-Methode für Button Catch 2, führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitCatch2(_ sender: UIButton)
  • Event-Handler-Methode für Button Catch 3, führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitCatch3(_ sender: UIButton)
  • Event-Handler-Methode für Button Try? (optional try), führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitTryOpt(_ sender: UIButton)
  • Event-Handler-Methode für Button Try! (forced try), führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitTryForce(_ sender: UIButton)
  • Event-Handler-Methode für Button Defer, führt Formel-Berechnung durch. Unabhängig vom Erfolg der Berechnung (d.h. auch dann wenn ein Fehler geworfen wird) werden die drei Slider auf zulässige Start-Werte gesetzt.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitDefer(_ sender: UIButton)
  • Event-Handler-Methode für Button OOP, führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitOOP(_ sender: UIButton)
  • Event-Handler-Methode für Button Guard, führt Formel-Berechnung aus.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitGuard(_ sender: UIButton)
  • Event-Handler-Methode für Button Assert, führt Formel-Berechnung durch. Wenn eine der drei Temperatur-Werte außerhalb des zulässigen Bereichs von echt-größer 0°C und echt-kleiner 100°C liegt, dann wird die App abgebrochen (aber nur wenn für Konfiguration DEBUG gebaut).

    Bitte in der Doku zu Methode berechnungDurchfuehren_Assert() nachlesen wie das Projekt für einen DEBUG-Build zu konfigurieren ist.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitAssert(_ sender: UIButton)
  • Event-Handler-Methode für Button FatalError, führt Formel-Berechnung durch. Wenn eine der drei Temperatur-Werte außerhalb des zulässigen Bereichs von echt-größer 0°C und echt-kleiner 100°C liegt, dann wird die App abgebrochen, und zwar unabhängig von der Build-Konfiguration.

    Declaration

    Swift

    @IBAction func onButtonBerechnungMitFatalError(_ sender: UIButton)
  • Methode sorgt dafür, dass zum Start die drei Textfelder den aktuellen Wert der jeweiligen Slider anzeigen. Außerdem wird das Textfeld für die Eingabe der Heißwassermenge so konfiguriert, dass nur zulässige Ganzzahlen eingegeben werden können.

    Declaration

    Swift

    override func viewDidLoad()
  • Funktion zur Anzeige eines Textes mit einem modalen Dialog (ohne Titel).

    Declaration

    Swift

    private func zeigeDialog(_ meldung:String)

    Parameters

    meldung

    Eigentlicher Meldungs-Text, der mit einem Dialog angezeigt werden soll.

  • Methode zum Auslesen der Kaltwassermenge in Liter, die im vom Outlet textFieldMengeHeissesWasser repräsentierten Textfeld gerade eingegeben ist. Dieses Textfeld ist so konfiguriert, dass nur positive Ganzzahlwerte (Milli-Liter) eingegeben werden können.

    Declaration

    Swift

    private func getHeisswasserLiter() -> Double

    Return Value

    Heißwassermenge in Liter

  • Methode zur Formatierung der Ergebnismenge (Liter kaltes Wasser) in einen Anzeige-String mit immer genau einer Nachkommastelle.

    Declaration

    Swift

    private func formatiereErgebnis(_ liter:Double) -> String

    Parameters

    liter

    Menge kaltes Wasser in Liter

    Return Value

    String mit formatierter Liter-Angabe, z.B. “0.3” oder “2.0”.

  • Methode zur Durchführung der eigentlichen Berechnung.

    Catch 1: Nur Default-Catch.

    Declaration

    Swift

    func berechnungDurchfuehren_Catch1()
  • Methode zur Durchführung der eigentlichen Berechnung.

    Catch 2: Mehrere Catch-Blöcke für verschiedene Fehler-Typen.

    Declaration

    Swift

    func berechnungDurchfuehren_Catch2()
  • Methode zur Durchführung der eigentlichen Berechnung.

    Catch 3: Ein Catch-Block mit Switch-Case zur Unterscheidung der verschiedenen Temperatur-Fehler.

    Declaration

    Swift

    func berechnungDurchfuehren_Catch3()
  • Methode zur Durchführung der eigentlichen Berechnung.

    Fehlerbehandlung mit sog. Optional Try (try?).

    Declaration

    Swift

    func berechnungDurchfuehren_OptionalTry()
  • Methode zur Durchführung der eigentlichen Berechnung.

    Fehlerbehandlung mit sog. Forced try (try!).

    Attention

    Wenn die Berechnungs-Funktion einen Fehler wirft, dann stürzt die App ab.

    Declaration

    Swift

    func berechnungDurchfuehren_ForcedTry()
  • Durchführung der Berechnung mit einem defer-Block, der unmittelbar vor Verlassen des umgebenden Blocks (hier: Rumpf der Methode) ausgeführt wird, egal wie der Block beendet wurde. Für die Fehlerbehandlung kann defer deshalb in etwa die Funktion des aus dem Exception-Handling bei anderen Programmiersprachen bekannten finally-Blocks übernehmen. In der Methode wird defer dafür verwendet, die Eingabewerte der drei Slider auf (zulässige) Start-Werte zu setzen, egal ob die Berechnung durchgeführt werden konnte oder ein Fehler an den Aufrufer hochgereicht wird.

    Attention

    defer kann auch für andere Dinge als Fehlerbehandlung eingesetzt werden.

    Attention

    Defer-Block wird nur dann wirksam, wenn er vor dem Verlassen des Blocks abgearbeitet wurde (er darf deshalb hier nicht nach dem Aufruf der Berechnungs-Methode, die einen Fehler werfen kann, stehen).

    See also

    Siehe diesen Gist für ein Java-Beispiel mit finally-Block.

    Throws

    Wenn die in dieser Methode aufgerufene Funktion berechneWassermenge() einen Fehler wirft, dann wird dieser einach an die aufrufende Methode (die Event-Handler-Methode) durchgereicht.

    Declaration

    Swift

    func berechnungDurchfuehren_Defer() throws
  • Diese Methode macht dasselbe wie die Methode berechnungDurchfuehren, verwendet statt der Funktion berechneWassermenge aber die Klasse MischTemperaturRechner.

    Declaration

    Swift

    func berechnungDurchfuehren_OOP()
  • Wie Methode berechnungDurchfuehren_OOP(), nur dass jetzt eine Instanz der Klasse MischTemperaturRechnerMitGuard verwendet wird, in der die Methode berecheKaltwassermenge() so überschrieben ist, dass die Fehler unter Verwendung des Schlüsselworts guardausgelöst werden.

    Declaration

    Swift

    func berechnungDurchfuehren_Guard()
  • Die Variante der Fehlerbehandlung verwendet zu Beginn einige assert-Statements, um Bedingungen (bool'scher Ausdrücke) zu definieren, die erfüllt sein müssen; ist eine dieser Bedingungen nicht erfällt, dann wird eine für die Konfiguration DEBUG gebaute App abgebrochen. Die im assert-Statement als zweiter Parameter übergebene Fehlerbeschreibung wird dabei auf der XCode-Konsole ausgegeben. Wenn die App für die Konfiguration RELEASE gebaut wurde, dann wird ein assert mit nicht erfüllter Bedingung einfach ignoriert.

    Konsole sichtbar machen:

    Die XCode-Konsole kann ggf. mit einer der folgenden beiden Möglichkeiten eingeblendet werden:

    • Menü-Eintrag: View | Debug Area | Activate Console
    • Tasten-Kombination: Shift+Cmd+C

    Die Konsole sollte rechts unten in XCode erscheinen.

    Build-Konfiguration einstellen:

    • Im Project Navigation auf den obersten Eintrag klicken (Projekt selbst).
    • In Hauptfenster auf Tab Build Settings.
    • Mit Suchfunktion nach SWIFT_OPTIMIZATION_LEVEL suchen.
    • Wenn als Wert “None [-Onone]“ eingestellt ist, dann wird ein DEBUG-Build erstellt, d.h. die App bricht bei einer nicht erfüllten Assertion ab.
    • Für einen anderen Wert (Fast, Single-File Optimization [-O] oder “Fast, Whole Module Optimization [-O -whole-module-optimization]“ wird ein RELEASE-Build erzeugt.
    • Über einen App-Store können nur RELEASE-Builds verteilt werden, d.h. das assert- Statement zur Fehlersuche kann nur für Haus-interne Tests verwendet werden.
    • Siehe auch diesen Blog-Artikel.

    Declaration

    Swift

    func berechnungDurchfuehren_Assert()
  • Diese Variante der Fehlerbehandlung verwendet die Funktion fatalError(), um bei einem ungültigen Wert für eine der drei Temperaturen die App abzubrechen (unbhängig von der Build-Konfiguration). Ein fatalError kann nicht abgefangen werden. Die der Funktion fatalError() übergebene Fehlermeldung wird in der XCode-Konsole ausgegeben; siehe Erklärung in Dokumentation zu Methode berechnungDurchfuehren_Assert(), wie diese Konsole eingeblendet werden kann.

    Declaration

    Swift

    func berechnungDurchfuehren_FatalError()
  • Event-Handler-Methode für den in der Methode viewDidLoad() definierten Tap-Recognizer, um das Keyboard wieder verschwinden zu lassen, wenn nach Eingabe in UITextField-Instanz an eine Stelle außerhalb des Keyboards getappt wird. Ruft auch Berechnung auf.

    Declaration

    Swift

    func keyboardVerschwindenLassen()
  • Methode aus Protocol UITextFieldDelegate überschreiben, damit nur Zahlen eingegeben werden können. Siehe auch diese Antwort auf stackoverflow.com. Methode wird für jeden Tastendruck (auch Loeschung) aufgerufen, also sind in replacementString einzelne Zeichen.

    Declaration

    Swift

    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool

    Return Value

    false wenn die Textänderung verworfen werden soll.

  • Nicht benötigte Methode

    Declaration

    Swift

    override func didReceiveMemoryWarning()