Scroll Brake : comment j'ai conçu un bloqueur iOS de 4 Mo contre le doomscrolling

Publié le 9 septembre 2026 dans Articles
Scroll Brake : comment j'ai conçu un bloqueur iOS de 4 Mo contre le doomscrolling

Comment la lutte contre les boucles de dopamine a donné naissance à Scroll Brake, pourquoi les ténors du secteur réclament des permissions suspectes et comment contourner les pièges de l'API Screen Time d'Apple.


Le piège des 45 minutes

Je suis intransigeant sur la productivité personnelle. Au fil des années, j'ai mis au point mon propre système de gestion du temps et de l'énergie, indispensable pour structurer mes journées et mener à bien des projets d'ingénierie complexes.

Pourtant, il arrive toujours un moment où, par pur automatisme, on prend son téléphone et commence à faire défiler des Reels. Une courte vidéo, une deuxième, une troisième… l'algorithme déverse un flux continu de stimuli captivants. On pensait souffler deux minutes, et 40 minutes ou une heure entière se sont déjà envolées. Les algorithmes de recommandation sont conçus par d'excellents ingénieurs dans un seul but : capter l'attention humaine à n'importe quel prix. Chaque balayage semble un peu plus gratifiant que le précédent, enfermant le cerveau dans une boucle de dopamine sans fin.

Je n'avais aucune intention de coder ma propre application. En tant que développeur et fondateur, mon temps est précieux et je privilégie toujours les solutions éprouvées. Je me suis donc tourné vers l'App Store.


Ce qui cloche avec les bloqueurs d'applications actuels

J'ai testé les références de la catégorie : Opal, OneSec, ScreenZen, Refocus, en plus de la fonctionnalité Temps d'écran intégrée par Apple. Très vite, j'ai été frappé par des choix d'architecture et d'ergonomie discutables :

Le paradoxe des notifications push

La première chose que demandent presque toutes ces applications est l'autorisation d'envoyer des notifications et de collecter des données analytiques. Pourquoi un outil censé réduire mon temps d'écran aurait-il besoin d'allumer mon téléphone avec des bannières ? Comme je l'ai compris plus tard en développant l'application, ce n'était pas de la mauvaise foi des développeurs, mais une contrainte historique du système iOS que j'explique en détail dans la partie technique.

Des écrans d'abonnement agressifs

Avant même d'avoir vu l'interface principale ou vérifié si l'outil répond à votre besoin, vous vous retrouvez face à un écran de paiement invasif. Le tout dissimulé derrière un « essai gratuit » calculé pour que l'utilisateur oublie de résilier à temps. En tant qu'entrepreneur, je comprends la rentabilité de ce modèle ; en tant qu'utilisateur, je refuse ces dark patterns.

L'inefficacité du Temps d'écran par défaut d'Apple

La solution native d'Apple échoue face aux réflexes humains. Dès que le panneau d'interdiction s'affiche, le pouce appuie machinalement sur « Ignorer la limite pendant 15 minutes ». Il n'y a aucune friction cognitive : le geste relève de la pure mémoire musculaire.

Je n'avais nulle envie d'écumer des dizaines de clones reposant sur des abonnements récurrents. Créer un outil léger et natif pour mon propre usage était à la fois plus rapide et plus honnête.


Les principes de Scroll Brake : 4 Mo, sans trackers, sans abonnement

Chez NovaSynapse, nous appliquons un principe directeur : « Tout ce dont vous avez besoin. Rien de superflu. » Un bon logiciel doit résoudre un problème précis, préserver l'autonomie de la batterie et respecter la tranquillité de l'utilisateur.

C'est ainsi qu'est né Scroll Brake :

  • Environ 4 Mo à l'installation : Aucun framework multiplateforme encombrant, pas de WebViews, zéro SDK tiers de traçage.
  • 100 % respectueux de la vie privée : Aucun compte utilisateur, aucune base de données distante, aucun serveur. Tout s'exécute localement sur l'appareil via les API natives d'iOS.
  • Friction cognitive plutôt qu'interdiction brute : Pour prolonger l'utilisation d'une application protégée, il faut solliciter son cortex préfrontal en résolvant un court calcul mental. Cette simple seconde de réflexion consciente suffit à briser le mode pilote automatique.
  • Sobriété anti-dopamine sans gamification : Une fois le calcul résolu, aucun feu d'artifice, aucun confetti ni message d'encouragement n'apparaît. Stimuler le cerveau avec de la dopamine bon marché parce qu'on déverrouille les réseaux sociaux n'a aucun sens. L'écran reste volontairement neutre et sobre : le temps est accordé, et le retour s'effectue via le bouton retour natif d'iOS situé en haut à gauche (pour préserver la confidentialité, iOS ne communique jamais à l'application hôte quelle app a déclenché le blocage, rendant toute redirection automatique impossible).
  • Modèle économique transparent : Jusqu'à 3 règles sont totalement gratuites à vie (je n'en utilise d'ailleurs qu'une seule au quotidien : la catégorie « Réseaux sociaux » limitée à 5 minutes par jour). Pour ceux qui souhaitent davantage de règles, j'ai instauré un achat unique à vie (Lifetime) plutôt qu'un abonnement forcé.

Conçu en 4 jours : IA et outils Xcode

J'ai développé l'application à l'aide d'assistants IA, en m'appuyant sur Antigravity et les modèles Gemini 3.1 Pro et Flash.

J'avais déjà une solide expérience du développement mobile avec Flutter et iOS natif, mais c'était avant la généralisation des assistants de code. Avec l'IA, mettre au point un utilitaire aussi ciblé s'est fait très rapidement. Cela ne dispense pas d'une rigueur absolue : les extensions système d'Apple sont notoirement délicates, et j'ai contrôlé chaque ligne de code pour éviter tout plantage ou fuite de mémoire. Au total, le projet m'a demandé entre 3 et 4 jours de travail, incluant les tests manuels sur appareils réels et versions antérieures d'iOS :

  • Icône finalisée en 15 minutes : Au lieu d'exporter manuellement des dizaines de calques PNG, j'ai utilisé l'outil développeur Icon Composer de Xcode. Ses calques vectoriels s'adaptent automatiquement aux thèmes clair, sombre et teinté d'iOS.
  • Validation App Store en moins de 24 heures : En l'absence de SDK de suivi et sans collecte de données personnelles, Apple a validé l'application dès le lendemain.

Plongée technique : les pièges de l'API Screen Time

Venons-en au cœur du sujet : l'architecture reposant sur ManagedSettings, DeviceActivity et FamilyControls. Lorsqu'on développe avec l'API Screen Time d'Apple, on se heurte inévitablement à trois blocages majeurs du système. Voici comment je les ai résolus :

Pourquoi la concurrence impose les notifications push (iOS < 26.5 vs iOS 26.5+)

Les utilisateurs se plaignent fréquemment des alertes répétées des bloqueurs d'applications, mais les développeurs ont longtemps été prisonniers du bac à sable (sandbox) imposé par Apple.

  • La contrainte historique :

Lorsqu'une application est bloquée, le système affiche un écran d'interception via ShieldActionExtension. Si l'utilisateur clique sur une action comme « Prolonger », cette extension s'exécute dans un sandbox restreint où l'appel à UIApplication.shared.open est strictement interdit à la compilation comme à l'exécution. L'énumération ShieldActionResponse ne proposait historiquement que .close, .defer et .none. Il était techniquement impossible de rouvrir l'application principale pour proposer un calcul ou une énigme !

  • La combine de l'industrie :

La seule parade consistait à envoyer une notification locale via UNUserNotificationCenter. L'utilisateur devait ensuite toucher la bannière pour ouvrir l'application hôte. C'est la raison exacte pour laquelle presque tous les bloqueurs de l'App Store réclament l'accès aux notifications.

  • La solution native avec iOS 26.5+ :

Apple a fini par introduire le cas ShieldActionResponse.openParentalControlsApp. Lorsqu'il est renvoyé, le système bascule immédiatement sur l'application hôte et affiche directement la vue du calcul mental (MathPuzzleView) :

  // ShieldActionExtension.swift
  defaults?.set(true, forKey: "launchedFromShieldAction")
  completionHandler(.openParentalControlsApp)

En ciblant iOS 26.5+ comme version minimale (IPHONEOSDEPLOYMENTTARGET = 26.5), j'ai pu supprimer l'intégralité de ces artifices de notifications.


Le cloisonnement du sandbox sur l'analyse d'utilisation

On me demande régulièrement : « Pourquoi l'application ne propose-t-elle pas des graphiques d'activité détaillés à la minute près ? »

La réponse est simple : Apple isole hermétiquement les données d'utilisation de l'application hôte.

  • L'accès au tableau de données DeviceActivityResults est accordé exclusivement à DeviceActivityReportExtension, qui tourne dans un processus système séparé.
  • L'application principale intègre uniquement un conteneur visuel : DeviceActivityReport. Il est rendu hors processus (out-of-process) et projeté au sein de l'interface utilisateur.
  • Les données brutes ne quittent jamais le sandbox : l'application hôte ne peut ni les enregistrer dans une base SQLite, ni les sérialiser, ni les transmettre sur un réseau.

La documentation officielle d'Apple le formule très clairement :

« Pour protéger la vie privée des utilisateurs, l'extension DeviceActivityReport s'exécute dans un bac à sable (sandbox) et ses données n'en sortent pas. À la place, l'extension génère et renvoie des vues que votre application affiche. »

  • Impact sur la surveillance :

Le contrôle des seuils via DeviceActivityCenter repose exclusivement sur un modèle d'abonnement à des seuils (DeviceActivityEvent.threshold). Le système avertit DeviceActivityMonitorExtension uniquement lorsque le palier est franchi (eventDidReachThreshold), sans transmettre de flux continu d'utilisation.

  • La raison du retour via la barre d'état :

Sous iOS, l'application hôte n'a aucun moyen de connaître le bundleIdentifier de l'application qui a déclenché le bouclier. Il est donc impossible de renvoyer l'utilisateur par programmation vers Instagram ou TikTok. Le retour s'effectue simplement en touchant le bouton retour système en haut à gauche de l'écran.


Contournement des bugs critiques de l'API Screen Time

Au cours des phases de test intensif, j'ai identifié des comportements inattendus d'iOS capables de paralyser n'importe quel bloqueur :

Bug de mise en cache des événements dans DeviceActivityCenter

  • Le problème : Lors de la mise à jour d'un palier pour un DeviceActivityName déjà actif pendant une prolongation, iOS omettait souvent de se déclencher sur le nouveau seuil.
  • La solution : Générer un identifiant d'activité unique intégrant un jeton de session DeviceActivityName("limit"), précédé d'un appel explicite à stopMonitoring().
  • Documentation Apple : DeviceActivityCenter.startMonitoring.
deviceActivityCenter.stopMonitoring([previousActivityName])
let newActivity = DeviceActivityName("limit_\(UUID().uuidString)_\(sessionToken)")
try deviceActivityCenter.startMonitoring(newActivity, during: schedule, events: events)

Le décalage de réinitialisation quotidienne (patron Dual-Event Schedule)

  • Le problème : Lorsqu'un DeviceActivitySchedule était paramétré avec repeats: true et que l'utilisateur ajoutait une prolongation d'une minute, le système appliquait par erreur ce même seuil d'une minute le lendemain matin au lieu de restaurer le quota journalier standard.
  • La solution : Enregistrer deux événements distincts dans un même planning :
  1. mainEvent : la limite journalière complète pour le jour suivant.
  2. extEvent : un événement temporaire intégrant la date du jour dans son nom et configuré pour expirer à 23h59.

Plantages de mémoire OOM (Code 11) dans DeviceActivityReport

  • Le problème : L'ajout de timers réactifs (comme des compteurs de secondes dans SwiftUI) au sein de la hiérarchie de DeviceActivityReport forçait des recalculs XPC permanents de l'historique sur 7 jours. Cela créait de rapides fuites de mémoire, entraînant l'arrêt brutal du processus par iOS pour dépassement de mémoire (erreur OOM code 11).
  • La solution : Éliminer totalement les timers réactifs des vues contenant des rapports, figer les paramètres de filtrage et rafraîchir les données uniquement lors des événements de cycle de vie (onAppear, willEnterForeground).

Ma configuration personnelle

Depuis sa mise en ligne, Scroll Brake est devenu mon rempart le plus efficace contre la dispersion d'attention.

Voici ma configuration quotidienne :

  • 1 règle : catégorie « Réseaux sociaux » verrouillée.
  • Limite de base : 5 minutes par jour.
  • Prolongation : 5 minutes accordées par calcul mental réussi.
  • Plafond de prolongations : 5 fois par jour maximum.

En pratique, je ne peux pas passer plus de 25 minutes par jour sur les réseaux sociaux. Mais le changement le plus profond est psychologique : mon cerveau sait désormais que regarder une vidéo partagée exige un effort conscient. Dans 8 cas sur 10, cette simple barrière suffit pour poser le téléphone et se remettre au travail.