Scroll Brake: cómo creé un bloqueador de 4 MB para iOS contra el doomscrolling
Cómo la lucha contra los bucles de dopamina dio origen a Scroll Brake, por qué los líderes del sector exigen permisos sospechosos y cómo sortear las trampas de Screen Time API en iOS.
La trampa de los 45 minutos
Me tomo muy en serio la productividad personal. A lo largo de los años he desarrollado mi propio sistema de gestión de tiempo y energía que mantiene mi jornada estructurada y me permite entregar proyectos de ingeniería complejos.
Aun así, hay momentos en los que tomas el móvil en piloto automático y empiezas a hacer scroll infinito en Reels. Un vídeo corto, otro más, un tercero… el algoritmo sirve un flujo interminable de estímulos. Pensabas tomarte un respiro de dos minutos y, de pronto, se han esfumado 40 minutos o una hora entera. Los algoritmos de recomendación están diseñados por ingenieros de primer nivel con un único objetivo: retener la atención humana al precio que sea. Cada swipe promete una recompensa mayor que la anterior, atrapando al cerebro en un bucle cerrado de dopamina.
No tenía la menor intención de crear mi propia aplicación. Como ingeniero de software y fundador, mi tiempo es limitado y siempre prefiero herramientas ya consolidadas. Así que fui directo al App Store.
Lo que falla en los bloqueadores actuales
Probé los referentes de la categoría: Opal, OneSec, ScreenZen, Refocus, además del Tiempo de Uso nativo de Apple. Casi de inmediato me topé con decisiones de arquitectura y diseño desconcertantes:
La paradoja de las notificaciones push
Casi todas estas herramientas empiezan pidiendo permisos de notificaciones push y analítica. ¿Por qué una app creada precisamente para alejarme del móvil necesitaría encender mi pantalla con avisos? Como descubrí más adelante al programar la app, esto no se debía a la codicia de los desarrolladores, sino a una limitación histórica de iOS que explico con detalle en el apartado técnico.
Pantallas de pago agresivas
Antes de ver la interfaz principal o comprobar si la solución sirve para tu caso, te recibe una pantalla de suscripción invasiva. Envuelta en un «periodo de prueba gratuito» calculado para que el usuario olvide cancelar a tiempo. Como emprendedor entiendo las métricas de conversión; como usuario, rechazo los dark patterns.
La ineficacia del Tiempo de Uso estándar de Apple
El Tiempo de Uso nativo de Apple fracasa por pura psicología humana. Cuando aparece la pantalla de bloqueo del sistema, el pulgar pulsa mecánicamente en «Ignorar límite durante 15 minutos». No existe ninguna fricción cognitiva: la acción se ejecuta por memoria muscular.
No tenía ganas de probar decenas de clones con idéntico modelo de suscripción recurrente. Construir una herramienta ligera y nativa para mí resultaba más rápido y, sobre todo, mucho más honesto.
Principios de Scroll Brake: 4 MB, sin rastreadores, sin suscripciones
En NovaSynapse nos guiamos por un principio claro: «Todo lo que necesitas. Nada que sobre.» Un buen software debe resolver el problema, cuidar la batería y respetar la privacidad del usuario.
Bajo esa filosofía nació Scroll Brake:
- Apenas 4 MB de tamaño: Sin frameworks multiplataforma pesados, sin WebViews y con cero SDKs de rastreo publicitario.
- 100 % enfocado en la privacidad: Sin cuentas de usuario, sin bases de datos remotas ni servidores externos. Todo se ejecuta en local en el dispositivo con las APIs nativas de iOS.
- Fricción cognitiva frente a prohibición ciega: Para extender el tiempo en una app bloqueada, hay que activar el córtex prefrontal resolviendo una breve operación matemática. Ese único segundo de esfuerzo consciente rompe el piloto automático.
- Diseño antidopamina sin gamificación: Al resolver el cálculo no hay confeti, ni animaciones festivas, ni mensajes de felicitación. Premiar al cerebro con dopamina barata por desbloquear redes sociales carece de sentido. La pantalla se mantiene sobria y tranquila: el tiempo se desbloquea y el regreso se realiza mediante el botón de retorno estándar de iOS en la esquina superior izquierda (por diseño de privacidad, iOS no revela a la app anfitriona qué app concreta activó el bloqueo, impidiendo redirecciones automáticas).
- Monetización justa: Hasta 3 reglas son completamente gratuitas para siempre (yo mismo solo uso una: categoría «Redes Sociales» limitada a 5 minutos diarios). Para quien necesite más reglas, implementé un pago único vitalicio en lugar de suscripciones periódicas.
Construido en 4 días: IA y herramientas de Xcode
Desarrollé la aplicación apoyándome en asistentes de IA, utilizando Antigravity y los modelos Gemini 3.1 Pro y Flash.
Ya contaba con experiencia previa en desarrollo móvil con Flutter e iOS nativo, pero aquello fue antes de la madurez de los asistentes de código. Con IA, crear un producto tan enfocado y ligero fue sorprendentemente rápido. Aun así, no puedes aceptar ciegamente el código sugerido: las extensiones del sistema de Apple son frágiles y requieren revisar cada línea para evitar fugas de memoria o cierres inesperados. El desarrollo completo, incluyendo pruebas en dispositivos reales y versiones previas de iOS, tomó entre 3 y 4 días laborables:
- Icono listo en 15 minutos: En vez de exportar capas de PNG a mano, utilicé la herramienta para desarrolladores Icon Composer de Xcode. Sus capas vectoriales se adaptan solas a los temas claro, oscuro y tintado de iOS.
- Aprobación en App Store en menos de 24 horas: Al carecer de SDKs de terceros y no recopilar datos privados, Apple revisó y aprobó la compilación al día siguiente.
Análisis técnico: las trampas ocultas de Screen Time API
Pasemos a la parte central: la arquitectura construida sobre ManagedSettings, DeviceActivity y FamilyControls. Cualquiera que trabaje con Screen Time API en iOS se topará con tres obstáculos estructurales. Así fue como los resolví:
Por qué la competencia recurre a notificaciones push (iOS < 26.5 frente a iOS 26.5+)
Muchos usuarios critican el exceso de notificaciones en los bloqueadores de apps, pero durante años los desarrolladores estuvieron atados de pies y manos por el sandbox de Apple.
- La limitación histórica:
Al bloquearse una app, el sistema muestra la pantalla protectora mediante ShieldActionExtension. Si el usuario pulsa un botón como «Extender tiempo», esa extensión se ejecuta en un sandbox donde invocar UIApplication.shared.open está estrictamente prohibido tanto a nivel de compilador como de sistema operativo. El enum ShieldActionResponse solo contemplaba .close, .defer y .none. No existía una vía legal para abrir la app principal y mostrar un reto o puzle.
- El parche de la industria:
La única salida técnica era disparar una notificación local mediante UNUserNotificationCenter. El usuario debía desplegar el Centro de Notificaciones o tocar el aviso para entrar a la app. Por eso casi todos los bloqueadores exigen permiso de notificaciones.
- La solución nativa en iOS 26.5+:
Apple incorporó finalmente el caso ShieldActionResponse.openParentalControlsApp. Al devolverlo, el sistema lanza de inmediato la aplicación anfitriona y presenta el puzle matemático (MathPuzzleView):
// ShieldActionExtension.swift
defaults?.set(true, forKey: "launchedFromShieldAction")
completionHandler(.openParentalControlsApp)
Al fijar iOS 26.5+ como despliegue mínimo (IPHONEOSDEPLOYMENTTARGET = 26.5), prescindí por completo de los trucos con notificaciones push.
El aislamiento del sandbox en analíticas de uso
A menudo me preguntan: «¿Por qué la app no muestra gráficas detalladas por minuto en su propia interfaz?»
La respuesta es tajante: Apple aísla los datos de Screen Time respecto a la aplicación anfitriona.
- El acceso a la colección
DeviceActivityResultsestá reservado en exclusiva a DeviceActivityReportExtension, que se ejecuta en un proceso de sistema independiente. - La app principal solo incrusta un contenedor visual: DeviceActivityReport. Este componente se renderiza fuera de proceso (out-of-process) y se proyecta sobre la vista de la app.
- La información en bruto jamás sale del sandbox: la app anfitriona no puede volcar estos registros en SQLite, serializarlos en memoria ni enviarlos por red.
La documentación oficial de Apple lo deja claro:
«Para proteger la privacidad del usuario, la extensión DeviceActivityReport se ejecuta en un sandbox y sus datos no salen de la extensión. En su lugar, la extensión crea y devuelve vistas que muestra tu aplicación.»
- Consecuencias en el monitoreo:
La supervisión de límites con DeviceActivityCenter opera únicamente mediante un modelo de suscripción a umbrales (DeviceActivityEvent.threshold). El sistema avisa a DeviceActivityMonitorExtension solo cuando se alcanza dicho umbral (eventDidReachThreshold), sin emitir telemetría continua de uso.
- El motivo del botón de retorno del sistema:
En iOS, la app no tiene forma de conocer el bundleIdentifier de la aplicación interceptada. Por ello no es posible redirigir automáticamente al usuario de vuelta a Instagram o TikTok. El retorno se hace simplemente pulsando el botón de retroceso que iOS coloca arriba a la izquierda.
Solución a fallos críticos de Screen Time API
Durante las pruebas intensivas salieron a la luz varios fallos del sistema iOS capaces de romper la fiabilidad de cualquier bloqueador:
Fallo de caché de eventos en DeviceActivityCenter
- El problema: Al actualizar el umbral para un
DeviceActivityNameexistente durante una extensión de tiempo, iOS ignoraba con frecuencia el nuevo límite. - La solución: Generar un identificador único con token de sesión
DeviceActivityName("limit, precedido de una llamada explícita a") stopMonitoring(). - Documentación de Apple: DeviceActivityCenter.startMonitoring.
deviceActivityCenter.stopMonitoring([previousActivityName])
let newActivity = DeviceActivityName("limit_\(UUID().uuidString)_\(sessionToken)")
try deviceActivityCenter.startMonitoring(newActivity, during: schedule, events: events)
El desajuste del reinicio diario (patrón Dual-Event Schedule)
- El problema: Si un DeviceActivitySchedule se configuraba con
repeats: truey el usuario añadía una extensión de 1 minuto, al día siguiente el sistema aplicaba por error ese mismo umbral de 1 minuto en vez de restablecer el límite diario completo. - La solución: Registrar dos eventos independientes en un mismo horario:
mainEvent: el límite diario habitual para el día siguiente.extEvent: un evento temporal con la fecha del día en su identificador, configurado para expirar a las 23:59.
Errores OOM (Código 11) en DeviceActivityReport
- El problema: Incluir temporizadores reactivos (como contadores por segundo en SwiftUI) cerca de la jerarquía de
DeviceActivityReportprovocaba peticiones XPC continuas para recalcular el histórico de 7 días. Esto desataba fugas de memoria y el cierre forzoso del proceso por Out-Of-Memory (código 11). - La solución: Eliminar por completo los temporizadores en las vistas con informes, mantener invariables los parámetros de filtrado y refrescar los datos únicamente ante eventos del ciclo de vida (
onAppear,willEnterForeground).
Cómo lo tengo configurado
Desde su lanzamiento, Scroll Brake se ha convertido en mi principal escudo contra la dispersión de atención.
Esta es mi configuración diaria:
- 1 regla: categoría «Redes Sociales» bloqueada.
- Límite base: 5 minutos al día.
- Extensión: 5 minutos adicionales por cada puzle matemático resuelto.
- Tope de extensiones: máximo 5 al día.
En la práctica no puedo pasar más de 25 minutos al día en redes sociales. Pero lo verdaderamente relevante es el hábito mental: mi cerebro asume que ver cualquier vídeo compartido exige un esfuerzo consciente. En 8 de cada 10 ocasiones, esa pequeña fricción basta para dejar el teléfono sobre la mesa y retomar lo que de verdad importa.