Les Extensions ajoutent de nouvelles fonctionnalités à des classes, structures et énumérations, que ce soient les votres ou pas.

En Swift, les extensions peuvent: 

  •  Ajouter des propriétés calculées d’instance et type
  • Définir des méthodes d’instance et de type
  • Créer de nouveaux constructeurs
  • Conformer un type à un protocole
  • ..

Déclaration d'une extension

class MyClass {
}
extension MyClass {
} 

J’ai ici créé une classe et créé une extension. Sa structure est la même que la classe. Le mot clé d’une extension est ‘extension’. Nous pouvons aussi ajouter des extensions à un type existant:

extension Int {
} 

Ajout de propriétés

Prenons par exemple notre extension de Int, nous allons y ajouter des propriétés calculées, pour convertir les secondes en minutes et en heures.

extension Int {
    var sec: Int { return self }
    var min: Int { return self / 60 }
    var hour: Int { return self / 3600 }
}

let seconds = 135682
let minutes = seconds.min
let hours = seconds.hour
print(“dans notre constante seconds il y a (seconds) secondes, (minutes) minutes et (hours) heures.”)

//dans notre constante seconds il y a 135682 secondes, 2261 minutes et 37 heures. 

Nous pouvons aussi ajouter une valeur calculée qui ne sera pas du même type bien évidemment: 

extension Int {
    var toString: String {
        let hours = self / 3600
        let remainHours = self % 3600
        let minutes = remainHours / 60
        let seconds = remainHours % 60
        return “(hours) heures, (minutes) minutes, (seconds) secondes”
    }
}
let seconds = 3769
print(seconds.toString)
//0 heures, 2 minutes, 49 secondes 

Ajout de méthodes

extension Int {
    func toDouble() -> Double {
        return Double(self)
    }
}
let seconds = 39
print(seconds.toDouble())
//39.0 

Ajout de constructeur

Nous pouvons aussi créer un constructeur dans une extension. Disons que nous voulons créer un autre init pour notre ordinateur. C’est une classe, nous aurons besoin d’un convenience init

class Ordinateur {
    var marque: String
    var modele: String
    var ram: Int
    var stockage: Int
    init(marque: String, modele: String, ram: Int, stockage: Int) {
        self.marque = marque
        self.modele = modele
        self.ram = ram
        self.stockage = stockage
    }
}
extension Ordinateur {
    convenience init(iMacWithRam ram: Int, stockage: Int) {
        self.init(marque: “Apple”, modele: “iMac”, ram: ram, stockage: stockage)
    }
}
 
let imac = Ordinateur(iMacWithRam: 16, stockage: 512) 

Et avec les Structures ?

Passons aux structures, nous pouvons créer notre propre init en plus de ce qui nous est créé automatiquement

struct Couleur {
    var red: Float
    var green: Float
    var blue: Float
    var alpha: Float
}
extension Couleur {
    init(dict: [String: Float]) {
        let red = dict[“red”] ?? 0
        let green = dict[“green”] ?? 0
        let blue = dict[“blue”] ?? 0
        self.init(red: red, green: green, blue: blue, alpha: 1)
    }
}
 
let newColor = Couleur(dict: [“red”: 0.4, “green”: 0.34, “blue”: 1] 

J’ai ici une structure qui permet de créer une couleur, je veux changer mon init par rapport à un dictionnaire. C’est possible. On peut faire ceci sur des types déjà existants.

Nous pouvons aussi utiliser les extensions pour bien séparer les protocoles et ainsi permettre à la classe de se conformer à un protocole. Nous voyons les protocoles dans le prochain chapitre.