Le tag porte l'URL du QR, rien d'autre : aucune entité, aucune colonne sur Section, aucun code NFC pour le cas nominal — l'OS lit le tag et c'est le lien universel qui aiguille. Ce qui reste à écrire, c'est la colle (assetlinks.json / AASA, routage du deep link), et elle répare au passage le QR code, qui n'ouvre jamais l'app depuis l'appareil photo. Prérequis dur : app.myinfomate.be doit être déployé pour servir les .well-known. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
7.5 KiB
Tags NFC — déclencher le contenu depuis un tag
Analysé dans le code le 2026-09-16. Carte kanban :
cards/5-planifie/265-…⚠️ Document retourné trois fois par les précisions de Thomas. Version arrêtée ci-dessous : le tag ouvre l'app mobile sur le bon contenu, et la page de téléchargement web reste le fallback quand l'app n'est pas installée.
Le comportement retenu
tag NFC (NDEF : URL du QR)
│
├─ app installée → App Link / Universal Link → mymuseum-visitapp s'ouvre sur la section
│
└─ app absente → app.myinfomate.be/download/{instanceId}/{configId}/{sectionId}
→ page « installez l'application » ← comportement actuel, conservé
Le tag porte exactement l'URL du QR. Pas d'entité NfcTag, pas de code opaque, pas
d'endpoint de résolution, pas de colonne sur Section. Un tag NFC est un QR code sans caméra —
c'est ce qui rend ce chantier petit.
✅ Et il n'y a aucun code NFC à écrire pour le cas nominal. Sur iOS (iPhone XS+) comme sur
Android, l'OS lit le tag NDEF, affiche une bannière et ouvre l'URL ; c'est le lien universel
qui aiguille vers l'app. nfc_manager, la permission NFC et l'entitlement Core NFC ne servent
qu'à la lecture in-app — utile seulement pour le bouton « Scanner un tag » du lot 4.
Ce qui manque vraiment : la colle
1. Les liens universels n'existent pas — c'est le cœur du chantier
Aucun assetlinks.json (Android) ni apple-app-site-association (iOS) n'est servi sur nos
domaines. Le seul du workspace est dans OpenGlasses, qui n'est pas à nous.
⚠️ Ils doivent être servis par le domaine de l'URL du tag, donc par app.myinfomate.be —
qui n'est pas déployé (absent de docker-compose-myinfomate.yml, qui route myinfomate.be,
api., manager. et monitor.). La carte « Déployer le visiteur web », déjà critical, reste
un prérequis dur.
À réunir avant d'écrire les fichiers : le SHA-256 de la clé de signature de release Android
(l'APK se construit par tool/build_apk.sh) et le Team ID + bundle id iOS. Une empreinte
fausse ne produit aucune erreur visible — le lien s'ouvre simplement dans le navigateur.
2. L'app n'écoute pas les deep links entrants
app_links est bien au pubspec.yaml:89, mais :
void _listenGlassesDeepLinks() {
if (!kEnableGlasses || !Platform.isAndroid) return; // ← main.dart:68
_deepLinkSub = AppLinks().uriLinkStream.listen(
(uri) => MetaGlassesService.instance.handleDeepLink(uri.toString()),
);
}
Tout part vers MetaGlassesService, le listener est coupé sur iOS et conditionné à
kEnableGlasses. Il faut router par motif d'URL, sans casser le retour de registration Meta.
3. La résolution d'un code est enfermée dans le dialogue du scanner
ScannerDialog._onDetect (ScannerDialog.dart:107) fait déjà tout ce qu'il faut : parsing
des trois formats de QR du terrain, section appartenant ou non à la visite en cours,
_findConfigurationIdOfSection quand l'id est brut, proposition d'ouvrir une autre visite du
site, et télémétrie. Mais c'est un State : la méthode manipule context, Navigator,
ScaffoldMessenger, et capture le navigator avant le pop pour survivre au démontage.
Extraire cette résolution dans un service est le vrai morceau de travail — et il profite au QR autant qu'au NFC. À faire sans perdre les cas limites, qui sont tous des corrections de bugs réels documentées en commentaires dans le fichier.
4. IsNFCEnabled, sur le modèle exact de IsQRCodeEnabled
ApplicationInstance.IsQRCodeEnabled (ApplicationInstance.cs:57, défaut true) est piloté par
un switch dans app_configuration_link_screen.dart:400 et consommé là où le bouton scanner
s'affiche : home_3.0.dart:651, configuration_page.dart:433, menu_page.dart:302, et
visitapp-web ([slug]/page.tsx:44). On ajoute IsNFCEnabled au même endroit, même défaut,
même switch.
⚠️ Ce que le flag pilote, et ce qu'il ne pilote pas. Il masque le bouton « Scanner un tag » in-app et sert de déclaration commerciale. Il ne peut pas empêcher un tag posé au mur d'ouvrir l'app : le deep link vient de l'OS, et l'app le reçoit sans savoir s'il vient d'un tag ou d'un QR. Ne pas lui prêter un rôle de verrou qu'il n'aura pas.
⚠️ Configuration.IsQRCode (Configuration.cs:52) existe aussi mais n'est lu par aucune app —
code mort. Ne pas dupliquer l'erreur en posant un flag NFC au niveau Configuration.
5. Sans quoi le NFC sera compté comme du QR dans les stats
_onDetect émet VisitEventType.qrScan. Un tag qui ouvre l'app par deep link n'a aucun moyen de
se distinguer — sauf à ajouter un paramètre à l'URL encodée sur le tag (?src=nfc) et une valeur
NfcScan à l'enum (VisitEvent.cs:48). ⚠️ L'enum passe par le client généré de
manager_api_new, à éditer à la main. Sans ça, le canal NFC est invisible dans les stats et
on ne saura jamais s'il sert.
(À traiter avec : la page de téléchargement dit « scannez à nouveau le QR code depuis
l'application » — faux pour un tag. Le ?src=nfc permet aussi d'adapter ce texte.)
Découpage
| Lot | Contenu | Estimation |
|---|---|---|
0 — Déployer app.myinfomate.be |
Carte existante, déjà critical. Prérequis dur : c'est ce domaine qui sert les .well-known |
(carte 210) |
| 1 — Liens universels | assetlinks.json + apple-app-site-association servis sur app.myinfomate.be, intent-filter autoVerify Android, Associated Domains iOS. Demande le SHA-256 de la clé de release et le Team ID |
1 j |
| 2 — Router le deep link entrant | Découpler main.dart:68 de MetaGlassesService, activer le listener sur iOS, router par motif |
0,5 j |
| 3 — Extraire la résolution du scanner | Sortir _onDetect de ScannerDialog vers un service, sans perdre les cas limites. ✅ Profite au QR |
1,5 j |
4 — IsNFCEnabled |
Colonne + DTO + client généré à la main + switch manager + i18n FR/EN/NL, et le bouton « Scanner un tag » qu'il pilote (nfc_manager, permission Android, entitlement iOS NDEF) |
1 j |
| 5 — Distinguer le canal | ?src=nfc sur l'URL encodée, VisitEventType.NfcScan, texte de la page de téléchargement |
0,5 j |
| 6 — Encoder les tags | NFC Tools, 2 s par tag, une URL par point. Geste d'exploitation | 0 j de dev |
Total : 4,5 j, dont les lots 2 et 3 réparent aussi le QR — aujourd'hui un QR scanné à l'appareil photo n'ouvre jamais l'app, même installée.
À savoir avant de le vendre
- iPhone XS et plus lisent un tag sans aucune app. Les iPhone 7 / 8 / X, non : il leur faut une app ouverte. Android : le NFC doit être activé dans les réglages, ce qui n'est pas universel.
- L'ouverture n'est pas automatique : l'OS affiche une bannière que le visiteur tape. C'est l'expérience de l'appareil photo sur un QR, pas mieux.
- Un tag à plat sur du métal ne se lit pas — tags sur mousse ou NTAG « on-metal ». NTAG213 (144 o) suffit largement pour l'URL.
- Aucune lecture NFC sur
visitapp-web: WebNFC est Chrome/Android uniquement, jamais Safari. Le plan Essentiel étant web-only, le NFC ne s'y vend pas — sauf comme « le tag ouvre la page web », qui reste vrai et gratuit. - Le NFC ne remplace pas le beacon : geste volontaire à 1-2 cm, aucun déclenchement à l'approche. Les déclencheurs se cumulent.