Protocoles en Swift : comment déclarer des méthodes optionnelles (analyse complète)

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Protocoles en Swift : comment déclarer des méthodes optionnelles (guide complet)

\n\n

Avez-vous déjà écrit un protocole en Swift et souhaité rendre une méthode optionnelle ? Pour qu'une classe qui adopte le protocole puisse ne pas implémenter cette méthode sans que le compilateur ne se plaigne ? Si oui, vous n'êtes pas seul. Cette question de Stack Overflow a recueilli des milliers de vues, et aujourd'hui nous allons enfin comprendre comment fonctionnent les optional methods dans un Swift protocol.

\n\n

Mais il y a un détail : Swift est un langage à typage strict, et il n'existe pas de méthodes optionnelles « pures ». En revanche, il existe plusieurs solutions élégantes. Nous allons examiner chacune d'elles, avec des exemples de code, afin que vous puissiez choisir celle qui convient à votre projet.

\n\n

Pourquoi Swift n'aime-t-il pas les méthodes optionnelles ?

\n\n

En Objective-C, les protocoles pouvaient marquer des méthodes comme @optional, et tout fonctionnait. Swift, quant à lui, a été conçu dès le départ pour la sécurité. Si un protocole déclare une méthode, alors toute classe qui l'adopte doit l'implémenter. Sinon, erreur de compilation. C'est génial car vous n'oublierez pas d'implémenter une méthode importante, et le code devient prévisible.

\n\n

Mais dans la vie réelle, on a souvent besoin de : « Implémente la méthode si tu veux, sinon utilise le comportement par défaut ». Comment faire ? Il existe trois méthodes principales.

\n\n

Méthode 1 : @objc et optional (classique, mais avec des réserves)

\n\n

La méthode la plus ancienne et la plus simple consiste à utiliser l'attribut @objc. Il transporte le protocole dans le monde du runtime Objective-C, où les méthodes optionnelles existent « nativement ».

\n\n
import Foundation\n\n@objc protocol DataSource {\n    @objc optional func fetchData() -> [String]\n    func mandatoryMethod()\n}\n\nclass MyViewController: UIViewController, DataSource {\n    func mandatoryMethod() {\n        print("Méthode obligatoire implémentée")\n    }\n    // fetchData() peut ne pas être implémentée\n}\n\n// Utilisation :\nlet vc = MyViewController()\nvc.fetchData?() // Appel sécurisé — rien ne se produit\nvc.mandatoryMethod()
\n\n

Avantages : simplicité, syntaxe claire, fonctionne avec les délégués.

\n

Inconvénients :

\n
    \n
  • Le protocole ne peut être utilisé qu'AVEC des classes (pas de structures, pas d'énumérations).
  • \n
  • L'ensemble du protocole doit être marqué @objc.
  • \n
  • Vous perdez certaines fonctionnalités spécifiques à Swift (associated types, where clauses).
  • \n
\n\n

Cette variante est idéale si vous développez pour iOS/macOS et travaillez avec UIKit (par exemple, les délégués UITableView). Mais pour du code Swift pur, il est préférable d'utiliser d'autres approches.

\n\n

Méthode 2 : Extensions de protocole avec implémentation par défaut (recommandée)

\n\n

C'est la méthode la plus « Swift-way ». Vous déclarez un protocole avec des méthodes obligatoires, puis dans une extension, vous fournissez une implémentation « par défaut » pour les méthodes que vous souhaitez rendre optionnelles.

\n\n
protocol Configurable {\n    func configureUI()\n    func setupBindings() // nous voulons la rendre optionnelle\n}\n\nextension Configurable {\n    func setupBindings() {\n        // Implémentation vide par défaut\n        print("Les bindings ne sont pas configurés (implémentation standard utilisée)")\n    }\n}\n\nclass MyView: Configurable {\n    func configureUI() {\n        print("UI configuré")\n    }\n    // setupBindings() peut être omise — l'implémentation de l'extension sera utilisée\n}\n\nclass AdvancedView: Configurable {\n    func configureUI() {\n        print("UI avancé")\n    }\n    func setupBindings() {\n        print("Mes propres bindings")\n    }\n}\n\nlet view = MyView()\nview.setupBindings() // Affiche : "Les bindings ne sont pas configurés (implémentation standard utilisée)"\n\nlet advanced = AdvancedView()\nadvanced.setupBindings() // Affiche : "Mes propres bindings"
\n\n

Pourquoi est-ce génial ?

\n
    \n
  • Fonctionne avec les classes, les structures et les énumérations.
  • \n
  • Entièrement natif Swift, sans objc.

Blogs

Book Recommendations