Feature Flags em Swift: como ativar funcionalidades sem novo build e sem quebrar a produção
Imagine: você lançou um novo tema escuro, e os usuários reclamam que o texto ficou ilegível. Ou adicionou um algoritmo complexo de recomendações que trava em iPhones antigos. No cenário clássico, você corrige o código, compila o build, passa pela revisão, espera a App Store — um dia ou mais. Durante todo esse tempo, o bug vive em produção.
Feature flags (ou feature toggles) — é uma técnica que permite ativar e desativar funcionalidades do aplicativo sem implantar novo código. Basicamente, são operadores condicionais que verificam o valor de uma flag, e o valor é armazenado remotamente — no servidor ou no Remote Config. Um interruptor — e a funcionalidade aparece para todos ou desaparece em segundos.
Neste artigo, vamos abordar como implementar feature flags em Swift, quais padrões usar e como não dar um tiro no pé. Vamos lá!
Por que usar feature flags no desenvolvimento iOS
Muitos pensam que feature flags são apenas para testes A/B. Na verdade, os cenários são muito mais amplos:
- Lançamentos canários (canary releases) — você ativa uma nova funcionalidade para 5% dos usuários, monitora crashes e, se tudo estiver bem, libera para todos.
- Kill switches — se algo der errado, você simplesmente desativa a funcionalidade remotamente, sem reverter o build.
- Rollout gradual — mostra a funcionalidade primeiro para iOS 17+, depois para versões mais antigas.
- Funcionalidades pagas — oculta recursos premium atrás de uma assinatura, gerenciando flags no backend.
- Experimentos e testes A/B — testa hipóteses em usuários reais, sem criar branches separadas.
Isso é especialmente relevante para projetos Swift, onde o binário é compilado uma vez e depois fica na loja. Sem feature flags, você não consegue reagir rapidamente a problemas — apenas com um novo release.
Arquitetura de feature flags em Swift
Uma implementação simples é um dicionário [String: Bool] vindo do servidor. Mas em um projeto real, é melhor criar uma abstração adequada. Aqui estão os componentes principais:
- FeatureFlagProvider — fonte de dados (Remote Config, sua API, arquivo local).
- FeatureFlagManager — singleton ou serviço que armazena em cache as flags e as fornece para as views.
- FeatureFlagKey — enum com chaves tipadas, para não espalhar strings pelo código.
Vamos escrever uma implementação simples, mas funcional, em Swift.
Passo 1. Definir o enum com as chaves
enum FeatureFlagKey: String, CaseIterable { case darkMode = "dark_mode" case newOnboarding = "new_onboarding" case premiumAnalytics = "premium_analytics" case experimentalFeed = "experimental_feed"}Usar enum em vez de strings garante que você não digitará errado o nome da flag. CaseIterable será útil para uma tela de debug.
Passo 2. Provider — obtendo flags do 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("Falha ao buscar remote config: \\(error?.localizedDescription ?? "")")