Inhaltsverzeichnis Danksagung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 Einleitung. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 1 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8 Datentypen und Optionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Willkommen auf dem Spielplatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Variablen und Konstanten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Zahlendatentypen konvertieren . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Werte runden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Minimum und Maximum. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Der Datenyp Bool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programmieren mit Optionals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 23 26 30 34 35 37 37 41 2 2.1 2.2 2.3 2.4 2.5 2.6 2.7 2.8 Zeichenketten des Typs String . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . String-Interpolation. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Zeichenketten vergleichen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Textabschnitte finden und ersetzen . . . . . . . . . . . . . . . . . . . . . . . . . . . Zeichenketten in Zahlentypen konvertieren . . . . . . . . . . . . . . . . . . . . Die Klasse NSNumber . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Texte teilen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Subscripting mit Unicode. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Anfang und Ende von Zeichenketten . . . . . . . . . . . . . . . . . . . . . . . . . 43 44 47 50 54 56 58 60 63 3 3.1 3.2 3.3 Arrays und Dictionaries . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arrays – Listen von Elementen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arrays sortieren und filtern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dictionaries, die schnellen Wörterbücher . . . . . . . . . . . . . . . . . . . . . . 67 67 72 75 4 4.1 4.2 4.3 4.4 4.5 Fallunterscheidungen und Schleifen . . . . . . . . . . . . . . . . . . . . . . . . . . Die if-Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die switch-case-Struktur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die for-Schleife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schleifen und Array. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Rückwärts durch die for-Schleife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 81 88 91 94 96 5 Inhaltsverzeichnis 6 4.6 4.7 4.8 4.9 Die while-Schleife . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Schleifen mit Fallunterscheidungen . . . . . . . . . . . . . . . . . . . . . . . . . . Diagramme im Ausgabebereich . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Gültigkeitsbereiche . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98 100 103 106 5 5.1 5.2 5.3 5.4 5.5 5.6 5.7 Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die erste Funktion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Benannte Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Funktionen mit Rückgabewert . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Tupel und anonyme Typen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Eine unbestimmte Anzahl von Parametern. . . . . . . . . . . . . . . . . . . . . Funktionen mit Standardwerten. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parameter sind unveränderlich. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 111 111 115 117 121 124 128 131 6 6.1 6.2 6.3 6.4 6.5 6.6 6.7 Closures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Closures sind Funktionen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Closures als Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arrays sortieren mit Closures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Variablen einfangen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchrone Closures mit Grand Central Dispatch . . . . . . . . . . . . . . . Parallele Verarbeitung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Asynchrone Aufrufe mittels Completion-Handler . . . . . . . . . . . . . . . 135 135 137 142 147 151 154 157 7 7.1 7.2 7.3 7.4 7.5 7.6 7.7 Klassen und Objekte . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Das erste Projekt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Erste Schritte im Workspace-Fenster . . . . . . . . . . . . . . . . . . . . . . . . . . Die Klasse Person . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Von der Klasse zum Objekt. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Eigenschaften und Punktnotation . . . . . . . . . . . . . . . . . . . . . . . . . . . . Berechnete Eigenschaften mit Getter und Setter . . . . . . . . . . . . . . . . Eigenschaften beobachten. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161 161 164 169 171 173 174 178 8 8.1 8.2 8.3 8.4 8.5 Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Methoden zur Initialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Failable Initializers – Wenn es mal schiefgeht . . . . . . . . . . . . . . . . . . Methoden zu Deinitialisierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Klassenmethoden. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Methoden kontra Eigenschaften . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 185 188 191 194 195 198 Inhaltsverzeichnis 9 9.1 9.2 9.3 9.4 9.5 9.6 9.7 Vererbung und Assoziationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Das Erbe der Klasse Person . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Erweiterungen der abgeleiteten Klasse . . . . . . . . . . . . . . . . . . . . . . . . Methoden überschreiben . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Die Initialisierung abgeleiteter Klassen . . . . . . . . . . . . . . . . . . . . . . . . Assoziationen – Beziehungen zwischen Objekten . . . . . . . . . . . . . . . Optional-Chaining . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Der Coalescing-Operator. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201 201 205 207 210 214 219 223 10 10.1 10.2 10.3 10.4 Protokolle und Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Ein eigenes Protokoll entwickeln . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Protokolle statt Datentypen. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Optionale Protokolle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 225 226 229 232 235 11 11.1 11.2 11.3 11.4 11.5 Strukturen und Enumerationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Zurück zum Spielplatz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Strukturen oder Klassen? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . String Dependencies – Abhängigkeiten von Zeichenketten . . . . . . . Enumerationen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enumerationen mit Methoden . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239 239 243 247 248 251 12 12.1 12.2 12.3 12.4 12.5 12.6 12.7 12.8 12.9 12.10 Lotto – 6 aus 49. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . MVC: Model-View-Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Projektvorlage – Cocoa Application . . . . . . . . . . . . . . . . . . . . . . . . . . . Der Lottozahlengenerator . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Der Interface Builder. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Inspector und Bibliothek. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Arbeiten mit dem Interface Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . Der Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Zurück zum Interface Builder . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Das war es jetzt schon? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . One more thing ... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 255 255 257 259 266 268 270 274 279 283 284 Swift Lexikon . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 287 Stichwortverzeichnis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 311 7 Einleitung Schnell, modern und sicher. Mit diesen drei Eigenschaften wurde die Programmiersprache Swift beschrieben, als sie am 1. Juni 2014 auf der WWDC-Konferenz in San Francisco erstmalig der Öffentlichkeit vorgestellt wurde. Für die Entwickler war dies eine große Überraschung, denn seit über 20 Jahren wurde bei der Firma Apple mit Objective-C programmiert, einer Sprache, die sich besonders in den letzten Jahren steigender Beliebtheit erfreute. Sollte jetzt alles neu und anders werden? Die Antwort auf diese Frage ist einfach: Ja! Tatsächlich bringt Swift Möglichkeiten für OS-X- und iOS-Projekte, die es in anderen Programmiersprachen schon seit vielen Jahren gibt. Typsicherheit, Closures und Optionals sind nur einige der Schlagwörter, mit denen Apple dafür sorgt, dass bei einigen Programmierern das Herz schneller schlägt. Sollten Ihnen die Begriffe bisher nichts sagen, dürfen Sie sich davon aber nicht zu sehr beeindrucken lassen. Sie werden diese, und viele andere, auf den folgenden Seiten noch sehr genau kennenlernen. Wie bei allen neuen Dingen ist die Skepsis der Entwickler zunächst groß, denn das Erlernen einer weiteren Programmiersprache braucht immer Zeit, und die ist für viele Programmierer, besonders jene, die mit der Softwareentwicklung ihren Lebensunterhalt verdienen, gleichbedeutend mit Geld. Allerdings ist auch Apple ein Unternehmen, das Profit erwirtschaften will, und eine neue Programmiersprache zu entwickeln, ist sicherlich kein Hobbyprojekt. Vermutlich verspricht man sich von Swift für Entwickler einen leichteren Zugang zu den Plattformen OS X und iOS und somit zusätzliche und vielleicht auch bessere Anwendungen. 11 Einleitung Wie die Zukunft für Swift aussehen wird, kann momentan niemand sagen. Es scheint aber unwahrscheinlich, dass Apple sowohl ObjectiveC als auch Swift weiterentwickeln wird. Dass bisher nur wenige Menschen mit Swift vertraut sind, ist hingegen sicher. Der Zeitpunkt, diese neue Sprache zu lernen, war daher nie besser. Dies ist Ihre Chance! An wen richtet sich das Buch? Trotz meiner guten Vorsätze, eine wirklich einfache Einführung der Sprache Swift zu schreiben, fängt auch diese Buch leider nicht bei Null an. Dafür reichen die zur Verfügung stehenden Seiten leider nicht aus. Wenn Sie als Leser aber schon ein wenig Erfahrung in einer anderen objektorientierten Programmiersprache haben und jetzt Swift lernen wollen, sollten die Beispiele für Sie keine großen Hürden sein. Dabei ist es auch unerheblich, ob Sie Vollzeitentwickler oder nur Hobbyprogrammierer sind. Sind Begriffe wie Compiler, Objekte und Vererbung für Sie keine Fremdwörter, dann steht Ihnen der Weg offen, ein erfolgreicher Swift-Entwickler zu werden! Swift ist vielen anderen Programmiersprachen sehr ähnlich, aber trotzdem werden sich die ersten Kapitel mit einfachen Dingen wie Datentypen und Kontrollstrukturen beschäftigen, denn selbst dort gibt es Besonderheiten. Ein Schwerpunkt liegt außerdem in der Verarbeitung und Manipulation von Zeichenketten, da fast kein Programm ohne die Ausgabe von Texten auskommt. Zusätzlich werden Sie Apples Entwicklungsumgebung Xcode kennenlernen, die in der aktuellen Version um einen »Spielplatz« erweitert wurde, mit dem man Swift besonders gut lernen kann. In den weiteren Kapiteln folgen dann ein wenig anspruchsvollere Themen wie Arrays, Dictionaries, Funktionen, Klassen und Methoden. Falls Ihnen Tuples, Optionals und Closures noch nicht vertraut sind, werden Sie diese ebenfalls kennenlernen. Nicht fehlen dürfen selbstverständlich die Themen Vererbung und Protokolle. Was wäre die objektorientierte Programmierung ohne sie? 12 Swift ist nicht Objective-C Version 3.0 Swift ist nicht Objective-C Version 3.0 Bevor es im nächsten Kapitel mit der Swift-Entwicklung losgehen kann, sind einige einführende Worte über die Programmiersprache nötig. Das gilt besonders für alle Entwickler, die bisher mit Objective-C auf den Apple-Plattformen gearbeitet haben. Einige Dinge, die Ihnen seit Jahren vertraut sind, funktionieren jetzt anders und müssen neu erlernt werden. Sieht man sich als erfahrener Entwickler den Quellcode eines SwiftProgramms an, bekommt man schnell den Eindruck, es mit einer weiteren auf C basierenden Sprache zu tun zu haben. Tatsächlich ist die Syntax von Swift anderen Sprachen der C-Familie in manchen Bereichen ähnlich, unterscheidet sich aber in anderen Teilen genauso oft. Swift ist zweifellos mit C verwandt, aber keineswegs mit der Sprache kompatibel. Das war bei Objective-C, der Sprache mit der für die ApplePlattformen bisher bevorzugt entwickelt wurde, anders. Sie können in Apples Xcode-Entwicklungsumgebung ein Objective-C-Projekt anlegen und dort ohne weitere Anpassungen 20 Jahre alten C-Code einfügen, ohne auf Probleme zu stoßen. Mit Swift funktioniert das nicht mehr. Die Sprache hat den Anspruch, sicher zu sein und muss deshalb Anforderungen erfüllen, auf die man in der Vergangenheit weniger Wert legte. So ist es beispielsweise nicht mehr möglich, bei einer ifStruktur auf den Block aus geschweiften Klammern zu verzichten. Einige andere Programmiersprachen erlauben das, wenn nur ein Befehl bedingt ausgeführt werden soll, aber es ist dann auch nur genau eine Anweisung. Ist der Programmcode jedoch ungünstig formatiert, kann es bei dem Entwickler leicht zu Fehlinterpretationen kommen. Mit Swift hat Apple sich das Ziel gesetzt, solche und ähnliche Situationen zu vermeiden. Nicht mehr schreiben muss man hingegen die runden Klammern, mit denen in vielen anderen Sprachen die Bedingung der if-Struktur eingeklammert wird. Im Gegensatz zu dem Block aus geschweiften Klammern erhöhen sie weder die Lesbarkeit noch die Sicherheit des Codes und auch sonst haben die Klammern keinen weiteren Nutzen. 13 Einleitung var value = 10000 if value == 10000 { println("Der Wert ist 10.000!") } else { println("Der Wert ist nicht 10.000.") } Ein Semikolon nach einer Anweisung ist in Swift ebenfalls nicht mehr erforderlich, der Compiler kann das Ende eines Befehls ohne diese Markierung erkennen. Sollten Sie trotzdem weiterhin Semikolons schreiben, vielleicht weil Sie das aus jahrelanger Gewohnheit automatisch tun, wird Ihr Code trotzdem akzeptiert. Nötig wird ein Semikolon nur, wenn Sie mehrere Anweisungen in eine Zeile schreiben wollen. Um den Programmcode lesbar zu halten, sollte man dies aber vermeiden. Wie Sie in den folgenden Beispielen sehen werden, benötigt ein SwiftProgramm auch nicht zwingend eine main-Methode, um starten zu können. Natürlich ist es wichtig, den Startpunkt einer Anwendung genau festzulegen, allerdings ermöglicht Swift auch Programme, die anders arbeiten. Ein »Playground« kann ein vollwertiges Programm in einer Datei abbilden, die von oben nach unten abgearbeitet wird. Im nächsten Kapitel werden wir uns mit diesem Dokumententyp und seinen Möglichkeiten detailliert beschäftigen. Sind Sie bereits Entwickler für die Apple-Plattformen, werden Sie vermutlich die eckigen Klammer vermissen, die in Objective-C immer zum Einsatz kamen, wenn mit Klassen und Objekte programmiert wurde. Auf diese besondere Syntax wurde in Swift ebenfalls verzichtet. Die Sprache verwendet stattdessen für Eigenschaften und Methodenaufrufe die Punktnotation, wie sie in Java und C# schon seit vielen Jahren üblich ist. Auch das Konzept, dass sämtliche Objekte im Speicher unabhängig voneinander existieren und nur durch Nachrichten mitei- 14 Kommentare nander kommunizieren, wird bei Swift nicht mehr angewendet. Dies führt zwar gegenüber Objective-C zu Einbußen in der Flexibilität, ermöglicht Swift im Gegenzug aber schnellere Methodenaufrufe. Kommentare Die Syntax der Schreibweise von Kommentaren hat sich im Vergleich zu C und Objective-C nicht verändert. Es gibt weiterhin zwei verschiedene Möglichkeiten, Anmerkungen im Programmcode zu hinterlegen. Die erste und einfachste ist die Kommentarzeile, eingeleitet durch zwei Schrägstriche. // Dies ist ein Kommentar. Kommentarzeilen eignen sich gut, um Variablen zu beschreiben. Es ist sogar möglich, den Kommentar direkt hinter einer Anweisung einzufügen. Nach den zwei Schrägstrichen wird der noch folgende Text zu einem Kommentar. // Das Alter der Person var ageOfPerson:Int = 45 var salaryOfPerson:Int = 45000 // Das Gehalt der Person Möchte man mehr als eine Zeile Kommentar in den Code einfügen, können komplette Abschnitte als Kommentarblock ausgewiesen werden. Mit der Zeichenfolge /* beginnt ein solcher Block, der mit */ wieder beendet wird. Neben dem Einsatz zur Dokumentation können Kommentarzeilen und Kommentarblöcke verwendet werden, um Anweisungen vorübergehend aus einem Programm zu entfernen. So müssen die Befehle nicht gelöscht werden, falls man sie zu einem späteren Zeitpunkt wieder benötigt. // Eine auskommentierte Anweisung /* var tax:Double = 0.19 */ 15