« Où est votre #ifdef ? » — la première question d'un développeur C en Swift
\n\nSi vous êtes déjà passé de C, C++ ou Objective-C à Swift, vous vous êtes sûrement demandé : « Comment faire de la compilation conditionnelle ici ? Où est mon #ifdef adoré ? » C'est l'une des questions les plus populaires sur Stack Overflow — et pour cause. Dans le monde Swift, il n'y a pas de préprocesseur au sens habituel, mais cela ne signifie pas que vous ne pouvez pas gérer flexiblement la compilation pour différentes plateformes, configurations ou modes de débogage.
\n\nDans cet article, nous allons analyser les meilleures façons de remplacer #ifdef en Swift : des directives simples aux schémas de build avancés. Vous apprendrez à écrire du code qui fonctionne à la fois sur iOS et macOS, à masquer les informations de débogage dans une version release et à ne pas vous perdre dans les drapeaux de plateforme. C'est parti !
\n\nPourquoi il n'y a pas de #ifdef en Swift (et c'est une bonne chose)
\n\nLe préprocesseur C est un outil puissant, mais dangereux. Il fonctionne avant le compilateur, ne connaît pas les types ni les portées. En conséquence, il est facile d'obtenir un #define qui casse tout autour. Les développeurs de Swift ont choisi une autre voie : ils ont intégré la compilation conditionnelle directement dans le langage, la rendant plus sûre et plus transparente.
Au lieu de #ifdef, vous utilisez #if, #elseif, #else et #endif — la syntaxe est similaire, mais elle fonctionne au niveau du compilateur Swift, et non du préprocesseur. De plus, ils ont ajouté plusieurs drapeaux intégrés, dont nous allons parler maintenant.
Approche 1 : Les directives classiques #if — le plus proche parent de #ifdef
\n\nLa façon la plus directe est d'utiliser #if avec des conditions prédéfinies :
#if DEBUG\n print("Ceci est une build de débogage")\n // Ici peuvent se trouver des logs, des vérifications supplémentaires\n#else\n print("Ceci est une build release")\n#endif\n\nVoici la liste des drapeaux intégrés que vous pouvez utiliser :
\n\n- \n
DEBUG— automatiquement défini pour la configuration Debug (Xcode l'ajoute lui-même) \n os(iOS),os(macOS),os(tvOS),os(watchOS)— vérification de la plateforme \n arch(x86_64),arch(arm64),arch(i386),arch(arm)— architecture du processeur \n swift(>=5.0)— version du langage Swift \n canImport(UIKit)— vérification de la disponibilité du module \n targetEnvironment(simulator)— fonctionnement sur simulateur \n
Exemple de vérification combinée :
\n\n#if os(iOS) || os(tvOS)\n import UIKit\n typealias PlatformView = UIView\n#elseif os(macOS)\n import AppKit\n typealias PlatformView = NSView\n#else\n typealias PlatformView = Any\n#endif\n\nCe code crée un alias unique pour la classe de vue, qui fonctionne sur différentes plateformes. Très pratique pour les bibliothèques multiplateformes !
\n\nApproche 2 : Active Compilation Conditions — votre propre #ifdef
\n\nEt si vous avez besoin d'ajouter votre propre drapeau qui n'est pas dans l'ensemble standard ? Par exemple, BETA_FEATURES ou PAYMENT_INTEGRATION. Pour cela, Xcode propose les Active Compilation Conditions (conditions de compilation actives).
Comment configurer :
\n- \n
- Ouvrez votre projet dans Xcode \n
- Sélectionnez target → Build Settings → Swift Compiler — Custom Flags \n
- Trouvez le champ Active Compilation Conditions \n
- Ajoutez vos drapeaux séparés par un espace, par exemple :
BETA PAYMENT_V2\n
Dans le code, on l'utilise ainsi :
\n\n#if BETA\n print("Version bêta lancée")\n showBetaUI()\n#endif\n\n#if PAYMENT_V2\n let paymentProcessor = NewPaymentProcessor()\n#else\n let paymentProcessor = LegacyPaymentProcessor()\n#endif\n\nC'est le remplacement direct de #ifdef de C/C++ ! Vous décidez vous-même