Introduction : Pourquoi Canary ne parle pas d'oiseaux ?
\n\nImaginez : vous publiez une nouvelle fonctionnalité dans votre application. Tout est testé, le CI/CD est vert, la revue de code est passée. Une heure plus tard — une avalanche d'avis négatifs, des bugs, des crashs. Cela vous dit quelque chose ?
\n\nDans le monde du développement iOS, il existe une solution élégante — les déploiements Canary (déploiements canaris). C'est une technique où la nouvelle version d'une fonctionnalité n'est reçue que par un petit pourcentage d'utilisateurs (généralement 1 à 5 %). Si tout va bien — on déploie pour tout le monde. Sinon — on annule avec un minimum de dégâts.
\n\nDans cet article, nous allons voir comment implémenter les déploiements Canary en Swift à l'aide de feature flags et de Firebase Remote Config. Pas de magie — seulement du code fonctionnel et des pratiques réelles.
\n\nQu'est-ce qu'un déploiement Canary et pourquoi en a-t-on besoin en Swift ?
\n\nLe terme vient de l'industrie minière : les mineurs emmenaient des canaris avec eux pour que leur état signale une fuite de gaz. En informatique — c'est la même chose : un petit groupe d'utilisateurs sert de « canari », montrant si la nouvelle version fonctionne.
\n\nPourquoi est-ce important pour les développeurs Swift ?
\n\n- \n
- Sécurité : Vous ne risquez pas tous les utilisateurs d'un coup \n
- Tests A/B : Vous pouvez comparer les métriques de l'ancienne et de la nouvelle fonctionnalité \n
- Flexibilité : L'annulation prend des secondes, pas des jours \n
- Contrôle : Vous pouvez activer ponctuellement la fonctionnalité pour les testeurs ou les bêta-utilisateurs \n
En Swift, nous utilisons des feature flags (indicateurs de fonctionnalités) — ce sont des variables booléennes qui activent/désactivent des fonctionnalités sans nouvelle compilation. Nous les combinons avec une configuration à distance (Firebase, LaunchDarkly) — et nous obtenons un déploiement Canary complet.
\n\nArchitecture d'un déploiement Canary en Swift
\n\nConstruisons un système simple mais fiable. Nous aurons besoin de :
\n\n- \n
- Feature Flag Provider — un service qui fournit le statut de la fonctionnalité \n
- Remote Config — un stockage distant des flags (nous utilisons Firebase) \n
- Logique de répartition — qui fait partie du groupe canari \n
- Monitoring — nous collectons les métriques et les rapports de crash \n
Étape 1 : Configuration de Firebase Remote Config
\n\nD'abord, ajoutez Firebase au projet. Si vous ne l'avez pas encore fait — suivez la documentation officielle. Ensuite, créez les paramètres Remote Config :
\n\n- \n
new_checkout_enabled— active le nouveau checkout \n new_checkout_percentage— pourcentage d'utilisateurs qui le verront (0.0–1.0) \n new_checkout_deadline— date d'activation complète (optionnel) \n
Dans la console Firebase, définissez les valeurs par défaut : false, 0.0, nil.
Étape 2 : Feature Flag Provider en Swift
\n\nCréons un protocole et son implémentation. Cela permettra de basculer facilement entre Firebase, les flags locaux ou les mocks pour les tests.
\n\nimport Foundation\nimport FirebaseRemoteConfig\n\n// MARK: - Protocol\nprotocol FeatureFlagProvider {\n func isFeatureEnabled(_ feature: FeatureFlag) -> Bool\n func percentage(for feature: FeatureFlag) -> Double\n func fetchRemoteConfig(completion: @escaping (Bool) -> Void)\n}\n\n// MARK: - Feature Flags\nenum FeatureFlag: String, CaseIterable {\n case newCheckout = "new_checkout_enabled"\n case newCheckoutPercentage = "new_checkout_percentage"\n case newCheckoutDeadline = "new_checkout_deadline"\n \n var defaultValue: Any {\n switch self {\n case .newCheckout: return false\n case .newCheckoutPercentage: return 0.0\n case .newCheckoutDeadline: return "" // ISO8601 string\n }\n }\n}\n\n// MARK: - Firebase Implementation\nfinal class FirebaseFeatureFlagProvider: FeatureFlagProvider {\n private let remoteConfig = RemoteConf