Scroll Brake: como criei um bloqueador de 4 MB para iOS contra o doomscrolling
A história de como a batalha contra loops de dopamina deu origem ao Scroll Brake, por que os principais concorrentes exigem permissões suspeitas e como contornar as armadilhas da Screen Time API da Apple.
A armadilha dos 45 minutos
Sou extremamente focado em produtividade pessoal. Ao longo dos anos estruturei um método próprio de gestão de tempo e energia que mantém minha rotina organizada e garante a entrega de projetos de engenharia complexos.
Mesmo assim, há momentos em que você pega o celular no piloto automático e começa a rolar Reels sem parar. Um vídeo curto, outro, um terceiro… o algoritmo entrega uma sequência interminável de estímulos. Você pensava em respirar por dois minutos e, de repente, se passaram 40 minutos ou uma hora inteira. Os algoritmos de recomendação são projetados por excelentes engenheiros com uma meta explícita: reter a atenção humana a qualquer custo. Cada rolagem parece ligeiramente mais compensadora que a anterior, prendendo o cérebro em um loop infinito de dopamina.
Eu não tinha intenção alguma de programar meu próprio aplicativo. Como desenvolvedor de software e fundador, meu tempo é escasso e sempre dou preferência a ferramentas consagradas. Por isso fui direto à App Store.
O que há de errado com os bloqueadores atuais
Testei as principais referências da categoria — Opal, OneSec, ScreenZen, Refocus, além do Tempo de Uso nativo da Apple. Quase de imediato me deparei com escolhas de arquitetura e design difíceis de justificar:
O paradoxo das notificações push
A primeiríssima coisa que praticamente todos esses apps solicitam são permissões para notificações push e telemetria analítica. Por que um utilitário criado para me afastar da tela precisaria acendê-la com alertas? Como descobri mais tarde ao construir o app, isso não acontecia por má-fé, mas sim por uma restrição histórica do próprio iOS que explico na seção técnica.
Telas de pagamento agressivas
Antes mesmo de visualizar a tela inicial ou conferir se a ferramenta atende às suas necessidades, você se depara com uma tela de cobrança invasiva. Tudo empacotado em um «período de teste grátis» claramente projetado na expectativa de que você esqueça de cancelar. Como empreendedor, entendo a lógica de conversão; como usuário, recuso esse tipo de dark pattern.
A ineficácia do Tempo de Uso nativo da Apple
A solução padrão da Apple falha diante da psicologia humana. No instante em que o escudo de bloqueio surge na tela, o polegar toca automaticamente em «Ignorar limite por 15 minutos». Não há qualquer fricção cognitiva: a reação é pura memória muscular.
Eu não queria perder tempo testando dezenas de clones dependentes de assinaturas periódicas. Percebi que construir uma ferramenta nativa, leve e direta para o meu dia a dia seria muito mais rápido e honesto.
Princípios do Scroll Brake: 4 MB, sem rastreadores, sem assinaturas
Na NovaSynapse, adotamos como lema: «Tudo o que você precisa. Nada além disso.» Um software de qualidade precisa resolver o problema real, poupar bateria e respeitar o espaço do usuário.
Foi assim que nasceu o Scroll Brake:
- Cerca de 4 MB de instalação: Sem frameworks multiplataforma pesados, sem WebViews e com zero SDKs de rastreamento de terceiros.
- 100% focado em privacidade: Sem contas de usuário, sem banco de dados remoto, sem servidores. Tudo é processado localmente no dispositivo usando as APIs nativas do iOS.
- Fricção cognitiva em vez de proibição cega: Para estender o tempo em um aplicativo bloqueado, é preciso ativar o córtex pré-frontal resolvendo um cálculo matemático rápido. Esse único segundo de esforço deliberado quebra o piloto automático.
- Design antidopamina sem gamificação: Ao acertar o cálculo, não há confetes, animações nem mensagens comemorativas. Estimular o cérebro com dopamina barata por liberar redes sociais seria contraditório. A tela é deliberadamente neutra e tranquila: o tempo é liberado e o retorno se dá pelo botão padrão de voltar do iOS no canto superior esquerdo (por questões de privacidade, o iOS não informa ao aplicativo anfitrião qual app disparou o bloqueio, impossibilitando redirecionamentos automáticos).
- Preço justo: Até 3 regras são totalmente gratuitas para sempre (eu mesmo utilizo apenas uma: categoria «Redes Sociais» limitada a 5 minutos diários). Para quem precisa de mais regras, criei uma compra vitalícia única (Lifetime), sem empurrar planos mensais ou anuais.
Criado em 4 dias: IA e ferramentas do Xcode
Desenvolvi o aplicativo com o suporte de assistentes de inteligência artificial, utilizando Antigravity e os modelos Gemini 3.1 Pro e Flash.
Eu já tinha experiência no desenvolvimento mobile com Flutter e iOS nativo, mas isso antes do surgimento das ferramentas de assistência de código. Com IA, a construção de um utilitário tão focado e enxuto avançou com extrema rapidez. Ainda assim, não se pode aceitar cegamente qualquer código sugerido: as extensões de sistema da Apple são bastante rigorosas, por isso revisei linha por linha para prevenir falhas de memória e encerramentos abruptos. Todo o desenvolvimento, somado a testes manuais em aparelhos físicos e versões anteriores do iOS, levou entre 3 e 4 dias úteis:
- Ícone em 15 minutos: Em vez de gerar manualmente dezenas de arquivos PNG, recorri à ferramenta Icon Composer do Xcode. As camadas vetoriais se ajustam sozinhas aos estilos claro, escuro e colorido do iOS.
- Aprovação na App Store em menos de 24 horas: Por não conter SDKs externos e não coletar dados pessoais, a Apple aprovou a compilação logo no dia seguinte.
Mergulho técnico: as armadilhas da Screen Time API
Chegamos à parte mais substancial: a arquitetura baseada em ManagedSettings, DeviceActivity e FamilyControls. Quem programa utilizando a Screen Time API da Apple inevitavelmente encara três barreiras do sistema operacional. Veja como as contornei:
Por que concorrentes apelam para notificações push (iOS < 26.5 vs iOS 26.5+)
Muitos usuários se queixam de notificações insistentes de bloqueadores de apps, mas por bastante tempo os desenvolvedores permaneceram limitados pelo sandbox da Apple.
- A restrição histórica do sistema:
Quando um aplicativo é bloqueado, o sistema projeta o escudo protetor por meio da ShieldActionExtension. Se o usuário seleciona uma opção como «Estender tempo», essa extensão opera em um sandbox protegido onde invocar UIApplication.shared.open é terminantemente proibido tanto pelo compilador quanto pelo sistema. O enum ShieldActionResponse contemplava apenas .close, .defer e .none. Não existia nenhuma forma legítima de abrir o aplicativo anfitrião para apresentar um desafio ou puzzle!
- A gambiarra comum do mercado:
A única alternativa técnica era disparar uma notificação push local via UNUserNotificationCenter. O usuário era obrigado a abrir a central de notificações e tocar no alerta para entrar no app. É exatamente por essa razão que praticamente todos os bloqueadores da App Store solicitam permissão de avisos.
- A solução nativa a partir do iOS 26.5+:
A Apple finalmente implementou o caso ShieldActionResponse.openParentalControlsApp. Quando retornado, o sistema abre imediatamente o aplicativo anfitrião exibindo a tela do puzzle matemático (MathPuzzleView):
// ShieldActionExtension.swift
defaults?.set(true, forKey: "launchedFromShieldAction")
completionHandler(.openParentalControlsApp)
Ao estabelecer o iOS 26.5+ como versão mínima suportada (IPHONEOSDEPLOYMENTTARGET = 26.5), eliminei integralmente qualquer necessidade de truques com notificações push.
O bloqueio do sandbox para telemetria de uso
É comum me perguntarem: «Por que o aplicativo não exibe gráficos detalhados de uso minuto a minuto em uma tela própria?»
A explicação é categórica: a Apple isola estruturalmente os dados de Screen Time do aplicativo anfitrião.
- O acesso ao conjunto
DeviceActivityResultsé concedido exclusivamente à DeviceActivityReportExtension, que opera em um processo isolado do sistema. - O aplicativo principal apenas embute um contêiner visual: DeviceActivityReport. Ele é renderizado fora do processo da aplicação (out-of-process) e projetado na tela do app.
- Os dados brutos jamais saem do sandbox: a aplicação anfitriã não tem como gravar esses registros no SQLite, serializá-los em estruturas de dados ou transmiti-los via rede.
A documentação oficial da Apple destaca:
«Para proteger a privacidade do usuário, a extensão DeviceActivityReport é executada em um sandbox e seus dados não saem da extensão. Em vez disso, a extensão cria e retorna exibições que o seu aplicativo mostra.»
- Impacto no monitoramento:
O acompanhamento de limites com o DeviceActivityCenter funciona estritamente por assinatura de limites predeterminados (DeviceActivityEvent.threshold). O sistema notifica a DeviceActivityMonitorExtension somente no instante em que a meta é batida (eventDidReachThreshold), sem enviar fluxo contínuo de dados.
- O motivo do retorno pelo topo da tela:
No iOS, a aplicação anfitriã não tem acesso ao bundleIdentifier do app bloqueado. Logo, não é possível redirecionar o usuário diretamente de volta para o Instagram ou TikTok via código. O retorno é feito tocando na seta de navegação nativa que o iOS posiciona no canto superior esquerdo.
Superando bugs ocultos da Screen Time API
Durante testes de estresse, encontrei comportamentos imprevistos do iOS que poderiam inutilizar qualquer bloqueador de apps:
O bug de cache de eventos no DeviceActivityCenter
- O problema: Ao ajustar o limite para um
DeviceActivityNamejá existente durante uma prorrogação, o iOS frequentemente deixava de acionar o novo patamar. - A solução: Criar um identificador de atividade único contendo um token de sessão
DeviceActivityName("limit, antecedido por uma chamada expressa a") stopMonitoring(). - Documentação Apple: DeviceActivityCenter.startMonitoring.
deviceActivityCenter.stopMonitoring([previousActivityName])
let newActivity = DeviceActivityName("limit_\(UUID().uuidString)_\(sessionToken)")
try deviceActivityCenter.startMonitoring(newActivity, during: schedule, events: events)
A falha de redefinição no dia seguinte (padrão Dual-Event Schedule)
- O problema: Se um DeviceActivitySchedule era configurado com
repeats: truee o usuário estendia o tempo por 1 minuto, na manhã seguinte o sistema aplicava equivocadamente esse mesmo limite de 1 minuto em vez de retornar ao limite integral do dia. - A solução: Registrar dois eventos distintos dentro do mesmo cronograma:
mainEvent: o limite diário padrão para o dia seguinte.extEvent: um evento transitório com a data do dia incorporada ao identificador, configurado para expirar às 23h59 de hoje.
Quedas por OOM (Código 11) no DeviceActivityReport
- O problema: Posicionar temporizadores reativos (como contadores de segundos em SwiftUI) próximos à hierarquia do
DeviceActivityReportforçava constantes reavaliações XPC do histórico de 7 dias. Isso gerava vazamento acelerado de memória e o encerramento do processo pelo iOS por esgotamento de memória (código 11). - A solução: Eliminar qualquer temporizador reativo nas telas com relatórios, fixar os parâmetros de filtragem e disparar atualizações exclusivamente em eventos de ciclo de vida (
onAppear,willEnterForeground).
Como configurei para o meu uso
Desde o lançamento, o Scroll Brake se tornou minha defesa central contra a fragmentação da atenção.
Minha configuração de uso diário:
- 1 regra: categoria «Redes Sociais» bloqueada.
- Limite base: 5 minutos ao dia.
- Prorrogação: 5 minutos adicionais por puzzle matemático solucionado.
- Teto de prorrogações: no máximo 5 vezes por dia.
Na prática, não posso passar de 25 minutos diários em redes sociais. Mas o maior ganho é na mudança de postura mental: meu cérebro passou a reconhecer que assistir a qualquer vídeo requer esforço consciente. Em 8 de cada 10 vezes, essa pequena fricção é suficiente para pousar o celular e focar no trabalho importante.