2. Swift sur iOS — Cours 1
Présentations
• Jean-Philippe Pellet, M.Sc. en informatique à l’EPFL,
Ph.D. à l’ETH Zurich/IBM Research
• Développement C, C++, Java, JavaScript, Objective-C,
Scala
• Depuis 2010:Wizbee, plateforme pédagogique, en Scala
• Depuis 2011: Cours de Java au 1er semestre EPFL
• Depuis 2013: HEPVaud, développements pédagogiques
2
3. Swift sur iOS — Cours 1
Organisation
• Horaire sur Google Drive
• Dossier partagé avec slides, exemple de code, etc.
➡ http://bit.ly/swift-hep
• Alternance entre sessions «cours» et
sessions «projet»
— Cours: 1 période de présentation, 1 période d’exercices
➡ Les exercices sont indépendants de tout projet
— Projet: 2-4 périodes de travail individuel «coaché»
➡ Optionnel, mais recommandé
➡ Selon vos projets personnels d’app ou des projets à définir ensemble
➡ Commande groupée de pizzas pour ceux qui font la soirée
3
4. Swift sur iOS — Cours 1
Prérequis
• OS X Mavericks (10.9.4+) ou Yosemite (10.10.1+)
• Xcode 6.1.1
• Pour les tests en vrai: un iPad ou iPhone avec iOS 8
— Sinon, les tests se font dans le simulateur
— Le simulateur ne simule pas tout (accéléromètre, location,
compas, etc.)
— Possibilité limitée d’emprunter des iPads de l’UER
(pendant les horaires du cours uniquement)
• Des connaissances de base en programmation
— Pas d’introduction aux principes des variables, des méthodes/
fonctions ou des classes/objets
4
5. Swift sur iOS — Cours 1
Thèmes proposés
• Bases d’Xcode, bases de Swift
• Swift plus en détails, programmation fonctionnelle
• Storyboards,Autolayout,View controllers
• Coaching technique; pizzas à 19h
• UITableView, données, gestes
• Widgets personnalisés, librairies utiles
• Coaching technique; pizzas à 19h
• Senseurs, CoreLocation
• Transitions, animations
• Coaching technique; pizzas à 19h
• CloudKit, CoreData
• Coaching technique; pizzas à 19h
5
6. Swift sur iOS — Cours 1
Mode
• Introduction d’un concept avec un morceau de code
commenté
• Discussion du concept sans forcément aller dans tous les
détails
• Le cours n’a pas la forme d’une référence
— Plus de découvertes illustrées par du code
6
7. Swift sur iOS — Cours 1
Références — livres (I)
• Swift (indépendamment d’iOS)
— The Swift Programming Language (ebook, env. 600 p.)
➡ La très bonne référence gratuite et complète d’Apple
— Swift in 24 Hours, Sams TeachYourself (420 p.)
➡ Excellente description quasi exhaustive de Swift
➡ Exercices, exemples courts et moyens
— Swift Fundamentals:The Language of iOS
Development (260 p.)
➡ Exercices rapides, description pragmatique du langage
➡ Qualité moyenne de mise en page
7
8. Swift sur iOS — Cours 1
Références — livres (II)
• iOS en Swift (avec exemples spécifiques)
— Beginning iPhone Development with Swift (800 p.)
➡ Toute une série d’introductions et exemples pratiques
sur des API de base (interface graphique, persistence
des données, dessin à l’écran
— iOS 8 Swift Programming Cookbook (870 p.)
➡ Série de chapitre de type use case – discussion – code.
Pratique pour copier-coller initial pour facilement
tester une série d’APIs
— iOS 8 for Programmers:An App-Driven Approach
with Swift (350 p.)
➡ 7 apps complètes expliquées en détails
8
9. Swift sur iOS — Cours 1
Références — Blogs
• https://developer.apple.com/swift/blog/
— Le blog d’Apple, pas extrêmement actif mais informatif et
facile à lire
• http://airspeedvelocity.net, http://nomothetis.svbtle.com
— S’intéressent de près au langage en profondeur
• http://robnapier.net
— Pas toujours beaucoup de code, discussions plus générales sur
la programmation fonctionnelle et ses paradigmes
9
10. Swift sur iOS — Cours 1
Références — Autres sites
• http://swiftdoc.org
➡ Documentation HTML générée automatiquement pour ce que Swift prédéfinit
• Swift Cheat Sheet
➡ Les bases résumées
• http://www.raywenderlich.com
➡ Une incroyable collection de tutoriels en ObjC ou Swift pour iOS
• Design patterns in Swift
➡ Approche objet-fonctionnelle des design patterns classiques
• https://github.com/pNre/ExSwift
➡ Des extensions aux types et collections de base
• https://thatthinginswift.com
➡ Je sais le faire en ObjC, mais pas en Swift…
10
11. Swift sur iOS — Cours 1
Références — Twitter
• @clattner_llvm — irrégulier, créateur de Swift
• @SwiftLang — 3–4x par mois
• @NSHipster — 2–3x par mois
• @mattt — 1–2x par mois
• @codinginswift — 1–2x par jour
• @AirspeedSwift — tous les 1–2 jours
• @cocoaphony — tous les 1–2 jours, pas que Swift
• @SwiftDevs — irrégulier
• @XcodeTips — irrégulier, Xcode
11
13. Swift sur iOS — Cours 1
Pourquoi Swift?
• Objective-C est vieux — 1983
• Très verbeux; séparation .h/.m; syntaxe unique
• Quelques évolutions du langage (ObjC 2, Modern ObjC,ARC)
• Swift est moderne, multiparadigme: orienté objet et fonctionnel
• Plus concis: simple de déclarer classes, méthodes, données, etc.
• Plus sûr: élimine (ou rend difficile) tout une série d’erreurs commune
avec ObjC
• Plus pratique: opérateurs, génériques, closures, etc.
• Approche fonctionnelle: code plus générique, plus facilement testable,
mieux adapté à des contextes d’exécution parallèle/concurrente
• Va probablement, à terme, remplacer ObjC
13
14. Swift sur iOS — Cours 1
Tester du code Swift
• Moyen le plus facile: un playground dans Xcode
— File → New → Playground
14
Code de test
Résultat de
chaque ligne
Output des
println()
Résultats multiples lors
d’une boucle
15. Swift sur iOS — Cours 1
Tester du code Swift
• Moyen le plus geek: le REPL (Read-Eval-Print-Loop) dans le terminal
— $ swift pourYosemite
— $ xcrun swift pour Mavericks
15
16. Swift sur iOS — Cours 1
Disclaimer
• Peu de personnes le sont…
• Mais:
— Connaissance approfondie de Scala et de ses principes
fonctionnels
➡ La plupart sont utilisable tels quels dans Swift
— Connaissance des framework iOS
16
Je ne suis pas un expert de Swift!
Je note toutes les questions auxquelles je n’ai pas
réponse immédiatement pour la prochaine séance
17. Swift sur iOS — Cours 1
Syntaxe de base — let, var
17
Syntaxe indispensable uniquement; on verra d’autres éléments de
syntaxe plus tard avec l’introduction d’autres concepts
let s = "String"
let i = 4
let c = Character("a")
let d = 2.0
• Pas de point-virgule; pas de @"String"
• let introduit une «variable» constante
— Même déclaration avec var à la la place de let: réassignable
— Mais on préfère les constantes!
➡ Moins de variables sont modifiables, plus le programme sera facile à lire (et à
optimiser)
➡ La programmation purement fonctionnelle (p. ex. Haskell) n’a que l’équivalent
des let
18. Swift sur iOS — Cours 1
Syntaxe de base — variables et types
• Dans l’exemple, pas de type déclaré. Mais Swift est
statiquement typé!
— C’est le compilateur qui infère le type
— On peut le spécifier manuellement; par exemple
18
let s: String = "String"
let i: Int = 4
let c: Character = Character("a")
let d: Double = 2.0
• Ceci ne marche pas; chaque variable a un type et un seul
var s = "String"
s = 10
Un Int n’est pas un String!
Ceci n’est pas du JavaScriptCeci n’est pas du JavaScript
19. Swift sur iOS — Cours 1
Syntaxe de base — variables et types
• On déclare le type d’une variable:
— Pour forcer un type différent que ce que le compilateur infère
— Pour documenter son code
— Pour assigner une variable plus tard
19
var str: String
if 12 / 3 == 4 {
str = "yes"
} else {
str = "no"
}
let l: Int64 = 4 // pour forcer un Int sur 64 bits
let result: String = crypticFunction()
20. Swift sur iOS — Cours 1
Syntaxe de base — commentaires
20
// Voici un commentaire terminé par un retour (C++ style)
/* Voici un bloc commentaire, terminé explicitement,
qui peut faire plusieurs lignes (C style) */
// Aussi utilisable pour commenter du code:
/*
func doWork() {
// TODO: implémenter cette fonction
/* Les commentaires C sont imbricables */
}
*/
Ceci n’est la fin que du
commentaire imbriqué — normal…
mais pas pour tous les langages!
MARK, TODO dans le
menu Xcode
21. Swift sur iOS — Cours 1
Syntaxe de base — if
21
let myString: String = ...
if myString == "Hello" {
println("Hello to you, too")
} else if myString == "Good bye" {
println("See you around")
} else {
println("Come again, please?")
}
• La condition: if ... { } else if ... { } else { }
— Sans parenthèses pour la condition
— Accolades obligatoires…
➡ On se souvient du goto fail;
22. Swift sur iOS — Cours 1
Digression — goto fail;
22
. . .
hashOut.data = hashes + SSL_MD5_DIGEST_LEN;
hashOut.length = SSL_SHA1_DIGEST_LEN;
if ((err = SSLFreeBuffer(&hashCtx)) != 0)
goto fail;
if ((err = ReadyHash(&SSLHashSHA1, &hashCtx)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &clientRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &serverRandom)) != 0)
goto fail;
if ((err = SSLHashSHA1.update(&hashCtx, &signedParams)) != 0)
goto fail;
goto fail; /* MISTAKE! THIS LINE SHOULD NOT BE HERE */
if ((err = SSLHashSHA1.final(&hashCtx, &hashOut)) != 0)
goto fail;
err = sslRawVerify(...);
. . .
23. Swift sur iOS — Cours 1
Syntaxe de base — for
• Boucle préférée: le for ... in ... { }
23
for index in 1...5 {
println("(index) times 5 is (index * 5)")
}
interpolation dans les strings!
let base = 3, power = 10
var answer = 1
for _ in 1...power {
answer *= base
}
println("(base) to the power of (power) is (answer)")
// "3 to the power of 10 is 59049"
• En ignorant la variable de boucle:
for var index = 0; index < 5; ++index {
println("index is (index)")
}
• Vieux style, avec var, à éviter
24. Swift sur iOS — Cours 1
Interpolation dans les strings
24
• Dans un string, le contenu entre ( et ) est évalué est
inséré dans le string directement
let user = "Steve"
let days = 3
let s1 = "posted by (user) (days) days ago"
NSString *user = @"Steve";
int days = 3;
NSString *s = [NSString stringWithFormat:@"posted by %@ %d days ago", user, days];
• En ObjC:
let w = 2
let h = 3
let s = "Area with sides (w) and (h) is (w * h)"
• Insertion d’expressions:
25. Swift sur iOS — Cours 1
Fonctions
• Les fonctions sont déclarées avec func
• Chaque paramètre indique son type
• Le type de retour, le cas échéant, est indiqué après ->
— Pas d’inférence des types ici
25
func sayHello(name: String) {
println("Hello, (name)!")
}
sayHello("Bill")
sayHello("Virginia")
func square(i: Int) -> Int {
return i * i
}
println(square(4))
println(square(32))
1 paramètre de type Int
Type de retour: Int
1 paramètre de type String
Type de retour: aucun
Void ou ()
26. Swift sur iOS — Cours 1
Fonctions
• Une fonction peut renvoyer plusieurs valeurs
— En fait, une seule valeur, mais de type Tuple
26
func firstAndLast(fullName: String) -> (first: String, last: String) {
if let range = fullName.rangeOfString(" ") {
let first = fullName.substringToIndex(range.startIndex)
let last = fullName.substringFromIndex(range.endIndex)
return (first, last)
} else {
return ("", "") // on fera mieux la semaine prochaine
}
}
let fullName = "Jean-Philippe Pellet"
let names = firstAndLast(fullName)
println("First name: (names.first); last name: (names.last)")
let (fst, lst) = firstAndLast(fullName)
println("First name: (fst); last name: (lst)")
type de retour (qui
nomme ses composants)
assignation du tuple à une
seule variable
assignation qui
déstructure le tuple
27. Swift sur iOS — Cours 1
Fonctions et variables
• Swift est fonctionnel: des paramètres peuvent être des
fonction, le type de retour peut être une fonction, les
variables peuvent contenir des fonctions…
— Dans ce sens, ressemble à JavaScript, mais avec des types
27
func makeGreeterFor(name: String) -> () -> Void {
return { () -> Void in
println("Hello, (name)!")
}
}
let greetLibby = makeGreeterFor("Libby")
greetLibby()
greetLibby()
makeGreeterFor("Hank")()
Type de retour de la fonction et
type de la variable: () ->Void —
«fonction qui ne prend aucun
argument et ne retourne rien»
Appels de la fonction stockée
dans la variable
Cet appel de fonction renvoie
une fonction
Appel direct de la fonction renvoyée
28. Swift sur iOS — Cours 1
• On appelle lambda une fonction anonyme déclarée pour être assignée à
une variable ou être retournée
• Un lambda, appelé closure lors de l’exécution, peut capturer des valeurs
de son contexte — ici, name
• Syntaxe générale:
{ (ParamTypes) -> ReturnType in ... return ... }
— Les types peuvent être omis si le contexte est clair
— Le return peut être omis si une seule expression
— On peut utiliser les placeholders $0, $1, $2 à la place de nommer les arguments
Lambdas
28
func makeGreeterFor(name: String) -> () -> Void {
return { () -> Void in
println("Hello, (name)!")
}
}
Ceci est le lambda
29. Swift sur iOS — Cours 1
Lambdas, exemples
29
let mult1 = { (d1: Double, d2: Double) -> Double in
return d1 * d2
}
let mult2 = { (d1: Double, d2: Double) -> Double in d1 * d2 }
let mult3 = { (d1: Double, d2: Double) in d1 * d2 }
let mult4: (Double, Double) -> Double = { $0 * $1 }
let mult5: (Double, Double) -> Double = (*)
println(mult1(3.0, 4.0))
println(mult2(3.0, 4.0))
println(mult3(3.0, 4.0))
println(mult4(3.0, 4.0))
println(mult5(3.0, 4.0))
Déclaration complète
On omet le return
(une seule expression)
On omet le return et le type de retour
On omet le nom des paramètres,
le contexte est clair
Les 5 fonctions font exactement la même chose
On utilise directement le nom de
la fonction à appliquer
30. Swift sur iOS — Cours 1
Fonctions génériques
• Une fonction générique ne connaît pas forcément les
types qui la définissent lorsqu’on l’écrit
• Après son nom, on met entre < > les types inconnus
• Les génériques sont très puissants mais assez complexes.
Exemple simple:
30
func callFunction<A, B>(f: A -> B, argument: A) -> B {
return f(argument)
}
callFunction(sayHello, "Max")
let greetMax = callFunction(makeGreeterFor, "Frank")
greetMax()
«J’accepte une fonction f qui prend un A et
retourne un B, et j’accepte un A. J’applique f
et je retourne le B que f me donne»
Pour sayHello: A = String, B =Void
On ne fait rien du résultat
Pour makeGreeterFor: A = String, B = () ->Void
On stocke le résultat (une fonction) dans une
variable, puis on l’appelle
31. Swift sur iOS — Cours 1
Types génériques: Array et Dictionary
• Des types bien pratiques qui sont aussi génériques
— Array<T> ou [T], analogue de NSArray
— Dictionary<K, V> ou [K: V], analogue de NSDictionary
31
let squares: Array<Int> = [0, 1, 4, 9, 16]
let squaresDict: Dictionary<Int, String> = [
0: "zero",
1: "one",
4: "four",
9: "nine",
16: "sixteen"
]
for i in 0 ..< squares.endIndex {
let squareVal = squares[i]
if let squareString = squaresDict[squareVal] {
println("(i) squared is (squareVal) or (squareString)")
}
}
array literal avec la notation entre [ ]
let dit aussi: l’array n’est pas modifiable
Son type est Array<Int> ou [Int]
dictionary literal avec la notation avec [ : ]
Son type est Dictionary[Int, String] ou [Int: String]
On reparlera du if let plus loin
Deux notations pour créer des Range:
x ..< y (y exclusif)
x ... y (y inclusif)
On ne stocke rien d’autre que les types déclarés
dans ces structures (contrairement à ObjC)
32. Swift sur iOS — Cours 1
Array et Dictionary modifiables
32
var odds = [Int]()
for i in 1...11 {
odds.append(i * 2 - 1)
}
println(odds)
println(odds[3])
var numbers = [Int: String]()
numbers[1] = "un"
numbers[2] = "deux"
numbers[80] = "huitante"
numbers[80] = "quatre-vingts"
println(numbers)
let valueFor80: Optional<String> = numbers[80]
println(valueFor80)
let valueFor60 = numbers[60]
println(valueFor60)
Les parenthèses après le nom du type appellent le
constructeur et construisent ici une structure vide.
Pas de new, init, alloc
Méthode append() pour ajouter des éléments
subscript entre [ ] pour accéder à une position particulière
Constructeur
Optional<T> contient soit rien (nil), soit un T.
On en reparle à fond la semaine prochaine!
subscript pour ajouter des éléments et
accéder à la valeur associée à une clé
33. Swift sur iOS — Cours 1
Résumé: Cours 1
• Playground, REPL
• Variables, constantes
• Strings et interpolation
• Conditions, boucles
• Fonctions, types fonctions, lambdas
• Génériques (fonctions)
• Array, Dictionary
33
34. Swift sur iOS — Cours 1
La semaine prochaine (provisoire)
• Classes, structs, enums
• Protocoles
• Pattern matching
• Optionals, optional chaining, ?, !, ??
• Programmation fonctionnelle
avec filter, map, flatMap
34