Architecture · SQLite · macOS 15

Où macOS stocke les alertes du Centre de notifications (group.com.apple.usernoted)

Comme macOS ne fournit aucune API publique pour observer les bannières des autres applications, tout outil de transfert doit lire la base SQLite maintenue par le démon usernoted. Voici comment elle est structurée sur macOS 15 Sequoia.

Mis à jour le · macOS 15.0 ou version ultérieure · essai de 7 jours

En bref

  • Sur macOS 15 Sequoia, les notifications actives sont stockées dans ~/Library/Group Containers/group.com.apple.usernoted/db2/db en mode SQLite WAL.
  • La table app associe chaque app_id à l’identifiant de bundle (identifier), et la table record stocke l’horodatage Core Data delivered_date ainsi qu’un plist binaire data.
  • Lire la base en mode WAL nécessite un accès en lecture au dossier db2 complet (db, db-wal et db-shm).
  • NotiFerry lit ce dossier en lecture seule dans l’App Sandbox via un signet sélectionné par l’utilisateur, sans jamais demander l’Accès complet au disque.

Pourquoi macOS ne propose aucune API publique pour lire les notifications des autres apps

Sur macOS, le framework officiel UNUserNotificationCenter permet uniquement à une application de programmer et d’inspecter ses propres notifications, associées à son identifiant de bundle. Contrairement au NotificationListenerService d’Android, macOS n’offre aucune API publique permettant à un utilitaire tiers de s’abonner aux bannières émises par les autres applications du Mac.

En pratique, le démon système par utilisateur usernoted reçoit toutes les notifications et les enregistre dans une base SQLite locale située dans le dossier de l’utilisateur :

# Dossier de la base du Centre de notifications par utilisateur sur macOS 15 Sequoia
~/Library/Group Containers/group.com.apple.usernoted/db2/

# Fichiers présents dans db2/
db        # Base de données principale SQLite 3
db-wal    # Journal Write-Ahead Log contenant les écritures récentes
db-shm    # Index de mémoire partagée pour les lecteurs WAL

Structure des tables SQLite de usernoted (db2)

Comme usernoted ouvre la base en mode Write-Ahead Logging (WAL), les nouvelles bannières se trouvent dans db-wal tant qu’un checkpoint ne les a pas fusionnées dans db. Tout outil qui interroge cette base doit donc disposer d’un accès en lecture au dossier db2 complet (et non au seul fichier db) afin que SQLite puisse lire simultanément db et db-wal.

  • app : associe un identifiant numérique app_id à l’identifiant de bundle de l’application émettrice (identifier, par exemple com.apple.dt.Xcode).
  • record : stocke chaque notification avec un identifiant croissant rec_id, la clé étrangère app_id, l’horodatage delivered_date (secondes écoulées depuis la date de référence Core Data d’Apple, 2001-01-01 00:00:00 UTC, soit 978307200 secondes après l’époque Unix) et un blob bplist00 dans data contenant req.titl (titre), req.subt (sous-titre) et req.body (message).
# Inspection en lecture seule des 5 dernières notifications (macOS 15)
sqlite3 -readonly \
  "$HOME/Library/Group Containers/group.com.apple.usernoted/db2/db" \
  "SELECT r.rec_id, a.identifier, datetime(r.delivered_date + 978307200, 'unixepoch') AS delivered_utc, length(r.data) AS bytes FROM record r JOIN app a ON r.app_id = a.app_id ORDER BY r.rec_id DESC LIMIT 5;"

Sécurité : signet en lecture seule sur un dossier vs Accès complet au disque

Sur macOS 15 Sequoia, le répertoire ~/Library/Group Containers/group.com.apple.usernoted est protégé par TCC (Transparency, Consent, and Control). Deux approches existent pour autoriser la lecture :

Modèle d’accèsAutorisation demandéeSurface exposée
Accès complet au disque (Full Disk Access)Réglages Système → Confidentialité et sécurité → Accès complet au disqueL’application peut lire Mail, Messages, l’historique Safari, les clés SSH et tous les fichiers du Mac
App Sandbox + signet de sécurité en lecture seule (NotiFerry)Sélectionner uniquement le dossier db2 dans la boîte de dialogue standard de macOSAccès en lecture seule strictement limité au dossier db2

NotiFerry utilise la seconde approche : il s’exécute dans le bac à sable macOS (App Sandbox), conserve un signet de sécurité en lecture seule sur db2, ouvre SQLite en mode lecture seule, résout le nom lisible de l’application émettrice, applique votre mode de confidentialité localement et transfère les nouvelles entrées vers ntfy.

Dans la barre des menus

Voir comment NotiFerry fonctionne sur votre Mac

Autorisez en lecture seule le dossier du Centre de notifications (sans Accès complet au disque), abonnez-vous à votre sujet privé dans l’application gratuite ntfy sur iPhone et confirmez la réception d’un test réel pour démarrer l’essai de 7 jours.

Télécharger l’essai de 7 joursbrew install --cask n2ctech/tap/notiferry
Ce qui arrive sur l’iPhone (dans ntfy)
ntfymaintenant

Claude Code — Autorisation requise

Autoriser l’outil Bash dans notiferry ? · Complète ou Titre seul

ntfy · rafale regroupéeil y a 2 min

Xcode — Compilation réussie (+4 alertes précédentes)

Tableau de bord NotiFerry sur macOS montrant le transfert activé, neuf notifications transférées pendant la session, le mode de confidentialité et le bouton de test vers l’iPhone
NotiFerry sur macOS : état du transfert, mode de confidentialité et confirmation de réception du test.

Questions

Où se trouve la base de données du Centre de notifications sur macOS 15 Sequoia ?

Sur macOS 15 Sequoia, la base SQLite par utilisateur est située dans ~/Library/Group Containers/group.com.apple.usernoted/db2/db (accompagnée des fichiers db-wal et db-shm).

Faut-il accorder l’Accès complet au disque pour lire les notifications macOS ?

Un script lancé depuis le Terminal a besoin que le Terminal dispose de l’Accès complet au disque. En revanche, une application macOS sandboxée comme NotiFerry peut demander à l’utilisateur de sélectionner uniquement le dossier db2 via NSOpenPanel et conserver un signet de sécurité en lecture seule sur ce seul dossier.

Version fondatrice

Un accès en lecture seule au seul dossier db2, sans Accès complet au disque.

L’essai de 7 jours ne débute qu’après votre confirmation qu’un test est arrivé sur votre iPhone. La licence coûte 9,99 € en paiement unique, pour 2 Mac. Un remboursement intégral peut être demandé dans les 30 jours ; les droits impératifs du consommateur restent inchangés.

Télécharger l’essai de 7 joursOu acheter une licence · 9,99 €brew install --cask n2ctech/tap/notiferryAchat unique · 2 Mac · validation périodique de la licence en ligne