Mémo ou CheatSheet Swift :

Variables et constantes

nil Absence de valeur pour une variable ou constante de type optionnel
Optional

var jeSuisOptionnel: Int?  // Ceci est un optionnel
var jeNeSuisPasOptionnel: Int // Ceci est un entier
Liaison facultative

if let variableDéballée = variableOptionnelle {
  print("La var déballée = \(variableDéballée)")
}

Gestion des erreurs

throws Sert à indiquer qu'une fonction peut renvoyer une erreur

func canThrowErrors() throws -> String
do
try
catch
Une méthode peut renvoyer des erreurs, donc pour l'appeler utiliser le mot clé try. Si la moindre erreur survient l'exécution du block s'arrête et la structure do-catch prend le relais.

do {
    try bankAccount.withdraw(400)
}
catch AccountError.TransactionExceedsFunds {
    print("Pas assez de fond")
}
assert Dans l'exemple ci-dessous, l'exécution du code s'arrête si la valeur de a est négative.

let age = -3
assert(age >= 0, "age can't be less than zero.")
print("bonjour") // Ne sera pas afficher

Boucles et conditions

in Parcourt les éléments d'une collection (tableau, ensemble, dictionnaire)

var act1SceneCount = 0
for scene in romeoAndJuliet {
    if scene.hasPrefix("Act 1 ") {
        act1SceneCount += 1
    }
}
continue L'instruction continue indique à une boucle d'arrêter ce qu'elle est en train de faire et de recommencer au début de l'itération suivante dans la boucle.

let puzzleInput = "great minds think alike"
var puzzleOutput = ""
let charactersToRemove: [Character] = ["a", "e", "i", "o", "u", " "]
for character in puzzleInput {
    if charactersToRemove.contains(character) {
        continue
    }
    puzzleOutput.append(character)
}
print(puzzleOutput)  // Prints "grtmndsthnklk"
break L' instruction break met immédiatement fin à l'exécution d'une instruction de flux de contrôle entière.
falltrough L'instruction fallthrough fait suivre au cas suivant

let integerToDescribe = 5
var description = "The number \(integerToDescribe) is"
switch integerToDescribe {
case 2, 3, 5, 7, 11, 13, 17, 19:
    description += " a prime number, and also"
    fallthrough
default:
    description += " an integer."
}
//  "The number 5 is a prime number, and also an integer."
guard Une instruction guard, comme une instruction if, exécute des instructions en fonction de la valeur booléenne d'une expression. Vous utilisez une instruction guard pour exiger qu'une condition soit vraie pour que le code après l'instruction guard soit exécuté. Contrairement à une instruction if, une instruction guard a toujours une clause else.

guard let location = person["location"] else {
    print("I hope the weather is nice near you.")
    return
}
aviable Vous utilisez une condition de disponibilité dans une instruction if ou guard pour exécuter conditionnellement un bloc de code, selon que les API que vous souhaitez utiliser sont disponibles au moment de l'exécution.

if #available(iOS 10, macOS 10.12, *) {
    // Use iOS 10 APIs on iOS, and use macOS 10.12 APIs on macOS
} else {
    // Fall back to earlier iOS and macOS APIs
}

Fonctions

inout Les paramètres de fonction étant des constantes par défaut, pour qu'un fonction modifie la valeur d'un paramètre, utilisez le paramètre inout. Placez une esperluette (&) avant le nom d'une variable :

func swapTwoInts(_ a: inout Int, _ b: inout Int) {
    let temporaryA = a
    a = b
    b = temporaryA
}  // Échange les valeurs de a en b, et de b en a

var someInt = 3, anotherInt = 107
swapTwoInts(&someInt, &anotherInt)

Les closures

in

{ (parameters) -> return type in
    statements
}
@escaping Une façon dont une closure peut s'échapper est d'être stockée dans une variable définie en dehors de la fonction.

var completionHandlers = [() -> Void]()
func someFunctionWithEscapingClosure(completionHandler: @escaping () -> Void) {
    completionHandlers.append(completionHandler)
}
@autoclosure Une @autoclosure vous permet de retarder l'évaluation, car le code à l'intérieur n'est pas exécuté tant que vous n'appelez pas la closure.

var customersList = ["Ewa", "Barry", "Daniella"]
func serve(customer: @autoclosure () -> String) {
    print("Now serving \(customer())!")
}
serve(customer: customersList(at: 0))

Les énumérations

CaseIterable /
allCases
Pour l'itération des cas d'une énumération

enum Beverage: CaseIterable {
    case coffee, tea, juice
}

let numberOfChoices = Beverage.allCases.count

for beverage in Beverage.allCases {
    print(beverage)
}
indirect Une énumération récursive est une énumération qui a une autre instance de l'énumération comme valeur associée pour un ou plusieurs des cas d'énumération.

enum ArithmExp {
    case number(Int)
    indirect case addition(ArithmExp, ArithmExp)
    indirect case multipl(ArithmExp, ArithmExp)
}

Classe et Structure

lazy Une propriété stockée différée (ou paresseuse lazy) est une propriété dont la valeur initiale n'est calculée qu'à la première utilisation. Toujours déclarer une propriété différée en tant que variable.

class DataManager {
    lazy var importer = DataImporter()
    var data = [String]()
    // the DataManager class would provide data  
     management functionality here
} 
get / set Action pour récupérer la valeur contenue get
Action pour modifier la valeur contenue set

class Carre {
    var longueur = 1
    var perimetre: Int {
        get {
            return longueur * 4
        }
        set {
            longueur = newValue / 4
        }
    }
}

let a = Carré()

a.longueur = 3
print(a.longueur) // Affiche 3
print(a.périmètre)  // 12 => Le setter modifie
S
a.périmètre = 16
print(a.longueur) // Affiche 4
print(a.périmètre)  // 16 => getter récupère valeur
willset /
didset
Deux méthodes pour observer des propriétés stockées :
willSet : la méthode est appelée juste avant la modification
didSet : la méthode est appelée juste après la modification

var longueur = 1 {
    willSet {
        print("Le carré va changer de taille")
    }
    didSet {
        if oldValue > longueur {
            print("Le carré a rapetissé")
        } else {
            print("Le carré a grandi")
        }
    }
}
private Le mot-clé private indique qu'une propriété (variable) n'est disponible que dans la structure auquelle elle appartient (Classe, énumération, structure)

struct Rectangle {
    private var height = 12
    /// ...
}
$variable Retour d'une valeur projetée
static S'applique à une propriété ou une méthode pour y accéder directement depuis son type (classe, structure ou énumération) sans passer par une instance :

class Math {
    static var py: Double = 3.14
    static func addition(_ a: Int, _ b: Int) -> Int {
        return a + b
    }
}
Math.py // Affiche 3.14
Math.addition(12, 3) // Affiche 15
self Permet d'accéder à une propriété ou une méthode appartenant à une classe, une structure ou une énumération :

class Math {
    let x: Int = 12
    func addToX (_ x: Int) -> Int {
        return self.x + x
    }
}
var a = Math()
a.addToX(3) // Affiche 15
mutating Permet de modifier une propriété à partir d'une fonction qui appartient à une structure ou à une énumération

struct Carre {
    var cote: Int = 12
    mutating func perimetre(_ newCote: Int) {
        cote = newCote
    }
}

var a = Carre()
a.perimetre(14)
print(a.cote)
override Permet de ré-écrire une méthode, une propriété ou un indice d'une classe mère à partir de sa classe fille :

class ClasseFille: ClasseMere {
    override func makeNoise() -> String {
        return "Chou Chou"
    }
}
super Permet d'accèder à une méthode ou propriété d'une classe mère depuis sa classe fille :

class ClasseFille: ClasseMere {
    override func makeNoise() -> String {
        return super.makeNoise() + " Chou Chou"
    }
}
final Empêche la modification override d'une classe, d'une propriété ou d'une fonction :

final class ClasseMere {
    func makeNoise() -> String {
        return "Boum Boum"
    }
}
convenience Permet de customiser l'initialiseur d'une classe fille
required Indique que chaque sous-classe de la classe doit implémenter cet initialiseur

class SomeClass {
    required init() {
        // initializer implementation goes here
    }
}
deinit Effectue un nettoyage manuel lorsque vos instances sont désallouées
as! Si je suis absolument certain du TYPE de variable

class Media {}
class Movie: Media {
    var director: String
    init(director: String) {
        self.director = director
    }
}

let library = [
    Movie(director: "Michael Curtiz"),
    Song(artist: "Elvis Presley"),
    Movie(director: "Orson Welles")
]

let mediaObj = library[0] as! Movie
as? Pour accéder à une variable d'un certain TYPE

class Media {}
class Movie: Media {
    var director: String
    init(director: String) {
        self.director = director
    }
}

let library = [
    Movie(director: "Michael Curtiz"),
    Movie(director: "Orson Welles")
]

var countMovie = 0

for item in library {
    if item is Movie {
        countMovie += 1
    }
}
is Pour juste savoir si une variable est d'un certain TYPE

class Media {}
class Movie: Media {
    var director: String
    init(director: String) {
        self.director = director
    }
}

let library = [
    Movie(director: "Michael Curtiz"),
    Movie(director: "Orson Welles")
]

var countMovie = 0

for item in library {
    if let movie = item as? Movie {
        print("C'est une video")
    }
}