Feature Flags en Swift: cómo activar funciones sin un nuevo build y no romper producción
Imagine: ha lanzado un nuevo modo oscuro y los usuarios escriben que el texto se ha vuelto ilegible. O ha añadido un algoritmo de recomendaciones complejo que en iPhones antiguos funciona con lentitud. En el escenario clásico, corrige el código, compila un build, pasa la revisión, espera a App Store — un día, o incluso más. Todo ese tiempo el error vive en producción.
Feature flags (o feature toggles) es una técnica que permite activar y desactivar la funcionalidad de la aplicación sin implementar nuevo código. Básicamente, son operadores condicionales que verifican el valor de una bandera, y el valor se almacena de forma remota — en un servidor o en Remote Config. Un interruptor — y la función aparece para todos o desaparece en segundos.
En este artículo, analizaremos cómo implementar feature flags en Swift, qué patrones usar y cómo no dispararse en el pie. ¡Allá vamos!
¿Para qué sirven los feature flags en el desarrollo iOS?
Muchos piensan que los feature flags son solo para pruebas A/B. En realidad, hay muchos más escenarios:
- Lanzamientos canary (canary releases) — activa la nueva función para el 5% de los usuarios, monitorea los crashes, y si todo está bien, la despliega para todos.
- Kill switches — si algo sale mal, simplemente desactiva la funcionalidad de forma remota, sin revertir el build.
- Despliegue gradual — muestra la función primero en iOS 17+, luego en versiones más antiguas.
- Funciones de pago — oculta las funciones premium detrás de una suscripción, gestionando las banderas en el backend.
- Experimentos y pruebas A/B — prueba hipótesis con usuarios reales, sin crear ramas separadas.
Esto es especialmente relevante para proyectos Swift, donde el binario se compila una vez y luego permanece en la tienda. Sin feature flags, no podrá reaccionar rápidamente a los problemas — solo a través de un nuevo lanzamiento.
Arquitectura de feature flags en Swift
Una implementación simple es un diccionario [String: Bool] que llega desde el servidor. Pero en un proyecto real, es mejor crear una abstracción adecuada. Estos son los componentes clave:
- FeatureFlagProvider — fuente de datos (Remote Config, su API, archivo local).
- FeatureFlagManager — singleton o servicio que almacena en caché las banderas y las entrega a las vistas.
- FeatureFlagKey — enum con claves tipadas para no esparcir cadenas por el código.
Escribamos una implementación simple pero funcional en Swift.
Paso 1. Definir un enum con las claves
enum FeatureFlagKey: String, CaseIterable { case darkMode = "dark_mode" case newOnboarding = "new_onboarding" case premiumAnalytics = "premium_analytics" case experimentalFeed = "experimental_feed"}Usar un enum en lugar de cadenas garantiza que no cometa errores tipográficos en el nombre de la bandera. CaseIterable será útil para una pantalla de depuración.
Paso 2. Proveedor — obtener banderas desde Firebase Remote Config
import FirebaseRemoteConfig
final class RemoteConfigProvider: FeatureFlagProvider { private let remoteConfig = RemoteConfig.remoteConfig() func fetchFlags(completion: @escaping ([String: Bool]) -> Void) { remoteConfig.fetch(withExpirationDuration: 3600) { status, error in if status == .success { self.remoteConfig.activate { _, _ in let flags = FeatureFlagKey.allCases.reduce(into: [String: Bool]()) { result, key in result[key.rawValue] = self.remoteConfig.configValue(forKey: key.rawValue).boolValue } completion(flags) } } else { print("Failed to fetch remote config: \\(error?.localizedDescription ?? "")")