Skip to Content
React Native9. APIs natives9.1 Le catalogue expo-*

Chapitre 9.1 — Le catalogue expo-* : le mode d’emploi

Où on en est : Drill maîtrise l’écran, les données, la base. Pour toucher au matériel (notifs, vibreur, capteurs), il faut le rituel des modules natifs — le même pour les ~80 modules du SDK.

⏱️ TL;DR — Chaque module expo-* = 4 étapes : installer (npx expo install), permissions (déclaratives dans app.json + demande à l’exécution), config plugin (si le module modifie le projet natif), utiliser. Les permissions Android se demandent AU MOMENT du besoin, avec un fallback gracieux si refusées. Certains modules exigent un development build — repérer la mention dans la doc AVANT de coder.

🎯 Objectifs

  • Dérouler le rituel install → permission → config → usage sur n’importe quel module.
  • Comprendre les deux étages de permissions Android (manifeste + runtime).
  • Savoir lire une page de doc Expo (les 4 sections qui comptent).
  • Reconnaître un module « Expo Go OK » d’un module « dev build requis ».

Lire une page de doc Expo

Ouvrez docs.expo.dev/versions/latest/sdk/haptics  — l’anatomie type :

  1. Le bandeau de compatibilité : plateformes (Android/iOS/web) et — crucial — si ça marche dans Expo Go ou s’il faut un development build. Réflexe n°1 : vérifier AVANT de coder.
  2. Installation : toujours npx expo install expo-<module> (la version alignée SDK, chapitre 1.4).
  3. Configuration : le config plugin éventuel (à ajouter dans plugins d’app.json) et les permissions requises.
  4. API : les fonctions, avec les patterns de permission.

Les permissions Android : deux étages

Étage 1 — le manifeste (déclaratif) : Android exige que l’app déclare ses permissions dans AndroidManifest.xml. Vous n’y touchez jamais : les config plugins des modules le font au prebuild, et app.json permet d’affiner :

// app.json — l'exemple type (les notifications, chapitre suivant) { "expo": { "plugins": [ ["expo-notifications", { "icon": "./assets/images/notification-icon.png", "color": "#087ea4" }] ], "android": { "permissions": [] // pour AJOUTER des permissions rares — la plupart viennent des plugins } } }

Étage 2 — le runtime (interactif) : depuis Android 6, les permissions sensibles se demandent à l’exécution, via une boîte système. Le pattern universel :

import * as Notifications from 'expo-notifications' async function ensureNotificationPermission(): Promise<boolean> { const current = await Notifications.getPermissionsAsync() if (current.granted) return true if (!current.canAskAgain) return false // refus définitif : ne PAS re-demander const asked = await Notifications.requestPermissionsAsync() return asked.granted }

Trois états à gérer, toujours : accordée, refusée mais redemandable, refusée définitivement (canAskAgain: false → la seule issue est les Paramètres système — Linking.openSettings() pour y emmener l’utilisateur, sans le harceler).

L’art de demander

Les règles UX qui font la différence entre une app polie et une app effrayante :

  1. Demander au moment du besoin, jamais au premier lancement : l’utilisateur qui active « Rappel quotidien » dans les Réglages comprend POURQUOI la boîte de permission apparaît. Le même dialogue à l’ouverture de l’app = refus quasi garanti.
  2. Pré-expliquer si l’enjeu est fort : un petit écran « Drill aimerait te rappeler ton défi quotidien » AVANT la boîte système double les taux d’acceptation (et préserve le canAskAgain).
  3. Fallback gracieux : permission refusée ≠ feature cassée. Pas de notifs → le Switch des Réglages reste off avec un lien « Autoriser dans les paramètres ». L’app fonctionne.

⚠️ Piège — Tester les permissions demande de la méthode : une fois accordée/refusée, la boîte ne réapparaît plus. Pour re-tester le flux complet : adb shell pm clear com.alex.drill (remise à zéro totale) ou révoquer dans Paramètres → Applications → Drill → Autorisations. Testez TOUJOURS le chemin « refusé » — c’est celui que vos utilisateurs les plus méfiants prendront.

💡 Pour un dev Next.js — Le web a ses permissions (géoloc, notifs) mais le navigateur gère la boîte et le blocage. Ici VOUS orchestrez le flux entier — en échange, l’éventail est immense : vibreur, capteurs, Bluetooth, arrière-plan… Le catalogue expo-* est votre nouvelle stdlib ; la compétence de ce chapitre (le rituel) est la clé de toutes ses portes.

✏️ Exercices

1. Sur trois modules que Drill utilisera (expo-notifications, expo-haptics, expo-audio), vérifiez dans la doc : Expo Go OK ? Config plugin ? Permission runtime ? Faites le tableau.

✅ Solution

ModuleExpo GoConfig pluginPermission runtime
expo-hapticsnonaucune (le vibreur « court » est libre)
expo-audiooptionnel (micro)aucune en lecture
expo-notifications⚠️ locales OK, push NONoui (icône/couleur)oui (Android 13+)

Leçon : même famille, exigences très différentes — d’où le réflexe bandeau de compatibilité.

2. Écrivez le helper générique ensurePermission réutilisable (get + canAskAgain + request) paramétré par les fonctions du module, puis dérivez ensureNotificationPermission.

✅ Solution

// lib/permissions.ts type PermissionAPI = { get: () => Promise<{ granted: boolean; canAskAgain: boolean }> request: () => Promise<{ granted: boolean }> } export async function ensurePermission(api: PermissionAPI): Promise<'granted' | 'denied' | 'blocked'> { const cur = await api.get() if (cur.granted) return 'granted' if (!cur.canAskAgain) return 'blocked' const res = await api.request() return res.granted ? 'granted' : 'denied' } export const ensureNotificationPermission = () => ensurePermission({ get: Notifications.getPermissionsAsync, request: Notifications.requestPermissionsAsync, })

Le retour à 3 états (‘blocked’ ≠ ‘denied’) force les appelants à gérer le cas openSettings.

3. Rédigez le micro-copy du pré-écran de permission pour le rappel quotidien de Drill (2 phrases max + 2 boutons). Qu’est-ce qui le rend efficace ?

✅ Solution

« Un défi par jour ? Drill peut te rappeler chaque soir de jouer ta session — une seule notification, jamais plus. » [Activer le rappel] [Plus tard]. Efficace : bénéfice concret (le défi), engagement borné (« une seule, jamais plus » — la peur n°1 est le spam), et le refus est indolore (« Plus tard » ne brûle pas le canAskAgain système puisque la vraie boîte n’apparaît qu’après le OUI).

🧠 Quiz

1. Quelles sont les 4 étapes du rituel d’un module expo-* ?

Réponse

Installer (npx expo install), permissions (manifeste via plugin + runtime), config plugin si le module touche au natif, utiliser l’API. Plus le réflexe zéro : vérifier la compatibilité Expo Go dans la doc.

2. Qui remplit AndroidManifest.xml dans un projet Expo ?

Réponse

Les config plugins des modules, au prebuild (CNG) — complétés au besoin par android.permissions d’app.json. Jamais d’édition manuelle.

3. Que signifie canAskAgain: false ?

Réponse

Refus définitif : la boîte système ne peut plus être montrée. Seule issue : les paramètres système (Linking.openSettings()) — proposé sans harcèlement.

4. Quand demander une permission ?

Réponse

Au moment du besoin, déclenchée par une action utilisateur qui l’explique (activer le rappel → boîte notifications) — jamais en rafale au premier lancement.

5. Comment re-tester un flux de permission déjà répondu ?

Réponse

adb shell pm clear <package> (reset complet) ou révocation manuelle dans Paramètres → Applications → Autorisations. Et toujours tester le chemin « refusé ».


👉 Chapitre suivant : 9.2 — Notifications locales — le défi quotidien, de la permission au deep link.