Chapitre 5.5 — Deep links : ouvrir l’app au bon endroit
Où on en est : Drill navigue parfaitement… quand on est dedans. Dernier maillon : y entrer directement au bon écran depuis l’extérieur — la notification du défi quotidien (Partie 9) en dépend.
⏱️ TL;DR — Le
scheme: "drill"d’app.json fait dedrill://…une porte d’entrée : chaque route est automatiquement un deep link avec Expo Router. Test :npx uri-scheme open "drill://quiz?theme=php" --android. Les écrans doivent être robustes à l’entrée directe (params validés, données manquantes gérées). Les App Links https (vérifiés par domaine) : panorama — utile le jour où Drill aura un site.
🎯 Objectifs
- Comprendre le chemin scheme → route → écran (rien à câbler : Expo Router mappe seul).
- Tester des deep links sur le téléphone/émulateur.
- Rendre les écrans robustes à l’ouverture directe (le contrat du chapitre 5.3 payé cash).
- Situer custom scheme vs App Links https.
Comment ça marche
Rappel chapitre 2.5 : "scheme": "drill" dans app.json. Au build, Android enregistre l’app
comme handler des URLs drill://. Expo Router fait le reste : l’URL est mappée sur vos
routes de fichiers, sans configuration :
drill:// → app ouverte (accueil)
drill://themes → onglet Thèmes
drill://themes/symfony → détail du thème Symfony
drill://quiz?theme=php&count=10 → une session PHP démarre !Deux cas de figure gérés automatiquement : app fermée (démarrage directement sur l’écran cible) et app en arrière-plan (ramenée au premier plan, navigation vers la cible).
Tester
# Sur l'émulateur ou le téléphone connecté (adb requis — chapitre 2.3)
npx uri-scheme open "drill://themes/symfony" --android
# Équivalent adb brut :
adb shell am start -a android.intent.action.VIEW -d "drill://quiz?theme=php&count=5"⚠️ Piège — Dans Expo Go, votre scheme
drill://n’existe pas (l’app conteneur a le sien :exp://). Les deep links custom se testent en préfixant :npx uri-scheme open "exp://192.168.1.x:8081/--/quiz?theme=php" --android(le/--/sépare l’adresse Metro du chemin). Le vraidrill://sera testable sur le development build (Partie 11) et l’APK (Partie 12). Notez la manip Expo Go quelque part — elle déroute tout le monde.
La robustesse d’entrée directe
Un écran atteint par deep link n’a aucun contexte : personne n’a « préparé » les données sur l’écran précédent. Trois contrats à respecter — et bonne nouvelle, on les a déjà posés :
- Params validés avec défauts (chapitre 5.3) :
drill://quiz?count=999→ borné à 50 ;?theme=inexistant→ thème mélange ou écran d’erreur propre. - Données chargeables depuis n’importe où : le détail d’un thème charge par slug (pas de « données passées par l’écran précédent » — anti-pattern de navigation).
- Pile de retour cohérente : back depuis un écran deep-linké doit mener quelque part de
sensé (l’accueil), pas fermer brutalement l’app. Expo Router reconstruit la pile d’après
l’arborescence (un deep link vers
/themes/symfonyplace/themesdessous) — testez-le.
Le cas d’usage réel arrive en Partie 9 : la notification « 🔥 Ton défi quotidien t’attend »
portera drill://quiz?theme=<aléatoire>&count=5 — tap → directement en jeu. C’est LE pont
notifications ↔ navigation.
App Links https — le panorama
Les schemes custom ont deux limites : n’importe quelle app peut déclarer drill:// (pas de
propriété), et un lien drill:// dans un navigateur ne fait rien si l’app manque. Les
Android App Links résolvent ça : des URLs https normales (https://drill.app/quiz)
vérifiées par un fichier assetlinks.json hébergé sur le domaine — l’app s’ouvre si installée,
le site sinon.
Configuration : intentFilters dans app.json + le fichier sur le domaine. Hors périmètre
pratique pour Drill (pas de site, pas d’hébergement — ADR 0001), mais sachez que ça existe :
le jour où une de vos apps a un site, c’est le standard. 🍏 Côté iOS : l’équivalent s’appelle
Universal Links (fichier apple-app-site-association).
✏️ Exercices
1. Testez trois deep links vers Drill dans Expo Go (accueil, détail Symfony, quiz avec params). Notez la commande exacte qui fonctionne chez vous.
✅ Solution
npx uri-scheme open "exp://<IP>:8081/--/" --android
npx uri-scheme open "exp://<IP>:8081/--/themes/symfony" --android
npx uri-scheme open "exp://<IP>:8081/--/quiz?theme=php&count=5" --android(IP = celle affichée par Metro.) Vérifier : l’écran cible s’affiche, et le back mène à un
endroit sensé. Le drill:// natif attendra le dev build.
2. Forgez un deep link hostile : …/--/quiz?theme=<script>&count=-3. Que doit-il se
passer, et où est le code qui le garantit ?
✅ Solution
Aucun crash : theme inconnu → fallback (mélange ou erreur propre), count=-3 → borné à 5
minimum. Le code : la lecture défensive des params dans app/quiz.tsx (chapitre 5.3). Un
deep link est une entrée utilisateur non fiable — au même titre qu’un formulaire.
3. Depuis l’écran résultat, ajoutez « Partager ce défi » : construire l’URL
drill://quiz?theme=X&count=N de la session et la copier au presse-papiers (anticipation
Partie 9 : expo-clipboard).
✅ Solution
import * as Clipboard from 'expo-clipboard'
const url = `drill://quiz?theme=${summary.theme}&count=${summary.count}`
<Button label="Copier le défi" variant="ghost"
onPress={() => Clipboard.setStringAsync(url)} />(npx expo install expo-clipboard.) Un ami avec Drill installé qui ouvre cette URL tombe sur
LA même config de session. Le partage complet (Share sheet) arrive en Partie 9.
🧠 Quiz
1. Que faut-il configurer pour que chaque route soit un deep link ?
Réponse
Uniquement le scheme dans app.json (“drill”) — Expo Router mappe automatiquement les URLs
drill://chemin sur l’arborescence de app/.
2. Comment tester un deep link custom dans Expo Go ?
Réponse
Via le scheme d’Expo Go : exp://<ip-metro>:8081/--/<chemin> (le /--/ sépare) avec
npx uri-scheme open … --android. Le scheme natif exige un dev build/APK.
3. Citez les trois contrats de robustesse d’un écran deep-linkable.
Réponse
Params validés avec défauts sûrs ; données chargeables par identifiant (aucune dépendance à l’écran précédent) ; pile de retour cohérente (back sensé).
4. Custom scheme vs App Links : deux différences clés ?
Réponse
App Links = URLs https réelles, vérifiées par le domaine (assetlinks.json) : propriété garantie + fallback web si l’app manque. Custom scheme = simple et sans domaine, mais non exclusif et sans fallback.
5. Quel usage de deep link Drill fera-t-il en Partie 9 ?
Réponse
La notification du défi quotidien : tap → drill://quiz?theme=…&count=5 → directement en
partie.
👉 Partie suivante : Partie 6 — État & formulaires — Zustand, la machine d’état d’une partie, et les réglages persistés : Drill devient jouable.