Vous êtes probablement arrivé au point où l'interface utilisateur est prête, l'écran de profil a un bouton « Télécharger une photo » et maintenant la partie facile n'est plus facile. La sélection réelle de l'image touche les permissions natives, les interfaces contrôlées par l'OS, les formes de retour différentes que beaucoup de développeurs attendent et une poignée de détails de construction qui ne se montrent que lorsque vous expédiez une vraie mise à jour.
C'est là que le sélectionneur d'images Expo entre en jeu. Il s'agit de la bibliothèque officielle d'Expo pour ouvrir l'interface système pour choisir des images et des vidéos à partir de la bibliothèque du dispositif ou prendre une photo avec la caméra, comme décrit dans le répertoire de packages Expo. En pratique, cela signifie que vous obtenez un pont fiable dans les entrées de médias natives, mais pas une expérience de médias personnalisée qui se comporte de la même manière sur chaque appareil.
Ce guide est écrit pour la première mise en œuvre, et non pour la démo. Il se concentre sur les décisions qui comptent en production : configuration de l'workflow géré ou non, gestion des permissions qui ne vous surprendront pas plus tard, analyse de résultats sûrs et modèle d'envoi pratique après que l'utilisateur ait sélectionné un fichier. Si vous travaillez dans un environnement natif personnalisé, il vous aide également à comprendre comment cela diffère d'un flux de client de développement Expo.
Table des matières
- Prise en main avec Expo Image Picker
- Installation et configuration essentielle
- Accéder à la caméra et à la bibliothèque multimédia
- Gestion des résultats et des options du sélecteur
- Modèles avancés et différences de plateforme
- Résolution de problèmes courants
Démarrage rapide avec l'Image Picker d'Expo
Un responsable produit demande des photos de profil. Une semaine plus tard, la même fonctionnalité nécessite également des téléchargements de factures, des captures de caméra pour les rapports d'incident et des retentes lorsque les utilisateurs refusent la permission la première fois. L'entrée d'image s'élargit rapidement car elle touche aux permissions natives, à l'interface utilisateur propriétaire de l'OS, à la gestion de fichiers temporaires et aux flux de téléchargement backend.
expo-image-picker est-ce que le module d'Expo SDK est fait pour cela. Il ouvre le sélecteur de plateforme ou l'interface utilisateur de la caméra et retourne les médias sélectionnés sous une forme que votre module React Native code peut gérer. Le JavaScript API est petit. Le principal défi réside dans la mise en place native, la gestion des permissions et la gestion des résultats corrects sur les projets gérés et non gérés.
Le principal compromis est clair. Vous laissez iOS et Android présenter leurs propres interfaces utilisateur de médias au lieu de construire un sélecteur personnalisé. Cela donne généralement un meilleur résultat : les utilisateurs comprennent déjà les écrans système, les invites de permission se comportent comme l'OS l'attend et votre équipe évite de maintenir une mise en page de galerie en JavaScript.
Intégration native traitée comme une fonctionnalité avec une interface React.
Cette mentalité est utile car les modes de panne sont rarement dans le bouton qui appelle le sélecteur. Ils proviennent généralement d'une des trois sources :
- Configuration native : configuration de plugin manquante, chaînes de permissions incorrectes, ou une compilation obsolète après avoir changé la configuration
- Comportement en temps de exécution : les utilisateurs peuvent refuser l'accès, accorder un accès limité à la bibliothèque sur iOS, ou annuler la progression sans sélectionner quoi que ce soit
- Analyse des résultats : le API actuel retourne un
assetstableau, donc les exemples plus anciens qui lisentresult.uridirectement échouent
Le choix du flux change également le chemin de configuration. Dans une application Expo gérée, la plupart du travail natif se trouve dans la configuration de l'application et nécessite une recompilation lorsque cette configuration change. Dans une application bare, vous obtenez toujours le module Expo API, mais vous devez vérifier les paramètres de projet iOS et Android plus directement. Si votre équipe utilise un client personnalisé au lieu d'Expo Go, ce guide se complète bien avec l'explication de Capgo sur comment un client de développement Expo modifie la testabilité des modules natifs.
That split matters for the rest de guide car les étapes heureuses ne sont que la moitié de l'histoire. Une mise en œuvre de sélection est solide quand elle fonctionne dans les deux workflows, gère les particularités de permissions spécifiques à la plateforme sans surprendre l'utilisateur, et passe un fichier utilisable à votre couche d'upload au lieu d'arrêter à une prévisualisation locale.
Installation et Configuration Essentielle
Installation nécessite une seule commande. Le paramétrage natif est ce qui détermine si le sélecteur fonctionne sur un appareil réel, dans un client de développement personnalisé, et dans votre build de production.
expo-image-picker gives a React-facing API over the platform pickers for photos, videos, and camera capture. The JavaScript call is simple. The setup is not, because photo access and camera access are controlled by iOS and Android, not by React Native.

Démarrez avec l'installateur version-aware d'Expo :
npx expo install expo-image-picker
Utilisez expo install au lieu de npm install ou yarn add. Expo correspond la version du package à votre SDK, ce qui évite un type commun de problèmes de compatibilité natives. Si vous comparez comment les modules Expo s'intègrent dans votre processus de publication, ce Vue d'ensemble des outils Expo est une référence utile.
Configuration de flux géré
Dans le flux géré, déclarez le plugin dans la configuration d'application afin que Expo puisse appliquer les modifications natives en temps de build.
Exemple avec app.json:
{
"expo": {
"plugins": ["expo-image-picker"]
}
}
C'est le minimum de configuration. Dans la pratique, les équipes ajoutent généralement du texte de permission, surtout sur iOS où la prompt système doit expliquer pourquoi l'application a besoin d'accès. Gardez le langage spécifique à l'action de l'utilisateur. « Télécharger une photo de profil » est mieux que « Besoin d'accès aux médias ».
Un détail opérationnel cause beaucoup de temps perdu. La modification des chaînes de permission ou d'autres configurations natives nécessite une nouvelle build. Le rechargement du JavaScript ne prend pas en compte ces modifications. Dans Expo Go, vous êtes également limité par ce que le client inclut déjà. Dans une build de développement ou de production, le projet native reflète votre configuration uniquement après une nouvelle build. pluginsDétails de configuration de React Native sans enveloppe
Dans une application sans enveloppe, le package __CAPGO_KEEP_0__ est le même, mais vous devez vérifier plus de projet native vous-même. Les descriptions d'utilisation iOS sont la première chose à vérifier. Si votre flux peut ouvrir la bibliothèque, lancer la caméra ou enregistrer une vidéo avec audio, votre application nécessite les chaînes de permission correspondantes dans
In a bare app, the package API is the same, but you need to verify more of the native project yourself. iOS usage descriptions are the first thing to check. If your flow can open the library, launch the camera, or record video with audio, your app needs the corresponding permission strings in Info.plist Un checklist pratique pour les projets sans enveloppe ressemble à ceci :
Installer
- avec
expo-image-picker__CAPGO_KEEP_0__npx expo install expo-image-picker. - Ajoutez la configuration du plugin si votre projet utilise des plugins de configuration Expo.
- Confirmez que les descriptions d'utilisation iOS correspondent aux fonctionnalités que vous exposez.
- Rebâtissez les applications iOS et Android après tout changement de configuration native.
Le texte de permission manquant ressemble souvent à un bug de temps d'exécution car l'interface utilisateur code est correcte et le gestionnaire de bouton fonctionne. L'erreur se situe plus bas dans la pile. Je vérifie généralement la configuration de l'application et si la dernière mise à jour inclut les changements natives avant de toucher le composant code. Info.plist, the app config, and whether the current build includes the latest native changes before I touch the component code.
Écrivez le texte de permission pour l'action réelle :
- les utilisateurs doivent comprendre pourquoi ils voient la prompt. Configurez la caméra et les bibliothèques séparément :
- l'une peut fonctionner tandis que l'autre continue de ne pas marcher. Rebâtissez après les changements natives :
- le rechargement chaud et la mise à jour rapide ne mettent pas à jour les permissions natives. Écrivez le texte de permission pour l'action réelle : les utilisateurs doivent comprendre pourquoi ils voient la prompt.
- Test sur appareil : Le comportement du simulateur peut masquer les problèmes de permission et de caméra.
Si le sélecteur fonctionne pendant le développement mais se brise dans TestFlight ou la mise en ligne de Google Play, considérez cela comme un problème de configuration en premier lieu. La plupart du temps, c'est le cas.
Accéder à la Caméra et à la Bibliothèque de Médias
Lorsque l'utilisateur appuie sur « Télécharger une photo », il s'attend à ce que la caméra ou la bibliothèque s'ouvre, et votre application a une seule tâche à ce moment-là. Ouvrez l'interface utilisateur système appropriée, gérez le refus ou l'annulation sans casser l'écran, et renvoyez une référence de fichier local utilisable pour la prévisualisation ou l'envoi.
Cela semble simple jusqu'à ce que vous testiez les builds gérés et non gérés sur iOS et Android. Le JavaScript API reste compact, mais le comportement en temps de exécution dépend toujours des invitations de l'OS, de l'équipement matériel du dispositif et de la façon dont vos permissions natives ont été configurées précédemment.

Un composant minimal mais sûr
Le flux de base est cohérent dans les projets de workflow Expo gérés et non gérés. Demandez la permission pertinente, lancez le sélecteur, vérifiez si l'utilisateur a annulé, puis lisez le premier élément de l'asset de result.assets.
Un composant de base ressemble à ceci :
import { useState } from 'react';
import { View, Button, Image, Alert } from 'react-native';
import * as ImagePicker from 'expo-image-picker';
export default function PhotoInput() {
const [imageUri, setImageUri] = useState<string | null>(null);
const pickFromLibrary = async () => {
const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
if (!permission.granted) {
Alert.alert('Permission required', 'Please allow photo library access.');
return;
}
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: true,
quality: 1,
});
if (result.canceled) return;
const asset = result.assets?.[0];
if (!asset?.uri) return;
setImageUri(asset.uri);
};
const takePhoto = async () => {
const permission = await ImagePicker.requestCameraPermissionsAsync();
if (!permission.granted) {
Alert.alert('Permission required', 'Please allow camera access.');
return;
}
const result = await ImagePicker.launchCameraAsync({
allowsEditing: true,
quality: 1,
});
if (result.canceled) return;
const asset = result.assets?.[0];
if (!asset?.uri) return;
setImageUri(asset.uri);
};
return (
<View>
<Button title="Choose from library" onPress={pickFromLibrary} />
<Button title="Take photo" onPress={takePhoto} />
{imageUri ? (
<Image
source={{ uri: imageUri }}
style={{ width: 200, height: 200 }}
/>
) : null}
</View>
);
}
Trois détails sont importants ici.
- Demander les permissions de la bibliothèque et de la caméra séparément. Elles échouent indépendamment.
- Traitez la suppression comme une action utilisateur normale, pas un état d'erreur.
- Lisez à partir de
assets[0], car le sélecteur retourne un tableau d'actifs plutôt qu'un élément de niveau supérieur.uri.
Flux de bibliothèque et de caméra
Démarrer avec le flux de bibliothèque si vous voulez la voie la plus rapide vers une fonctionnalité fonctionnelle. Il est plus facile à tester, il fonctionne dans plus de configurations de simulateur, et il évite les cas d'extrémité de matériel de la caméra. Ajoutez ensuite la prise en charge de la caméra une fois que le chemin de gestion des résultats est stable.
Le chemin de la caméra a plus de façons de fail en développement. La prise en charge du simulateur iOS est limitée. Les émulateurs Android peuvent ne pas exposer le comportement de la caméra qui correspond à un appareil réel. Dans les projets bare, ces lacunes peuvent vous faire chercher dans le composant code même si le problème réel est la configuration native ou l'environnement de test.
Un modèle de conception de l'interface utilisateur propre est de demander à l'utilisateur la source avant d'appeler le sélecteur API:
const showPickerOptions = () => {
Alert.alert('Upload image', 'Choose a source', [
{ text: 'Camera', onPress: takePhoto },
{ text: 'Photo Library', onPress: pickFromLibrary },
{ text: 'Cancel', style: 'cancel' },
]);
};
Cette séparation maintient chaque fonction focalisée. Cela rend également plus facile d'ajouter des analyses, des drapeaux de fonctionnalité ou des règles spécifiques au serveur ultérieurement. Par exemple, certaines équipes autorisent les téléchargements de bibliothèque pour les images de profil mais exigent des captures de la caméra fraîches pour la vérification d'identité.
Si votre application plus large prend également en charge des modèles d'accès aux fichiers en dehors d'Expo ou que vous comparez des conventions entre les stacks natives, cela Capacitor référence de la bibliothèque photo est utile dans le contexte.
Un démo court est utile lorsque vous montrez ce flux à des collègues ou à la QA :
What to attendir de l'interface utilisateur du système
expo-image-picker ouvre le sélecteur de plateforme ou l'interface utilisateur de la caméra. Votre application ne contrôle pas chaque écran dans ce flux. Cette distinction compte car « cela fonctionne sur mon appareil » signifie souvent « l'OS a autorisé le chemin que j'ai testé »
Sur iOS, les utilisateurs peuvent accorder un accès de bibliothèque limité au lieu d'un accès complet. Sur Android, le comportement du sélecteur peut varier en fonction de la version du système d'exploitation et de la peau du fabricant. Dans les projets de flux géré, Expo gère plus de la mise en œuvre native pour vous. Dans les projets de flux bare, vous devez confirmer que votre application compilée inclut les modifications de permissions natives que vous avez apportées. Le site d'appel JavaScript peut être identique dans les deux cas, tandis que le résultat de temps de exécution diffère.
Je teste généralement ces cas avant d'appeler la fonctionnalité terminée :
- première demande de permission
- permission refusée
- annulation de l'utilisateur
- sélection de bibliothèque réussie
- captation de la caméra réussie sur un appareil physique
- prévisualisation immédiate de la URI locale retournée
Ces cas correspondent directement au comportement de production réel. Ils mettent également en place l'étape suivante de manière propre si vous devez envoyer le fichier à un serveur, une chaîne de traitement de moderation ou un point de terminaison de publication tel que le Instagram media publishing API.
Gestion des Résultats et Options du Sélecteur
Le résultat du sélecteur est la partie qui nécessite généralement une logique de production réelle. L'interface utilisateur du système retourne un objet structuré, et non juste un chemin de fichier, et de petites erreurs ici entraînent des prévisualisations brisées, des téléchargements vides ou des plantages après que l'utilisateur annule.
Lecture de l'objet de résultat correctement
La forme de résultat qui compte dans les applications Expo actuelles est result.assets[0].uri, pas un élément de niveau supérieur result.uriCe détail affecte à la fois les projets de workflow gérés et les projets de workflow bare car le JavaScript API est le même même si la mise en place native diffère en dessous.
Utilisez un modèle de garde en premier :
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: true,
quality: 1,
});
if (result.canceled) {
return;
}
const asset = result.assets?.[0];
if (!asset) {
return;
}
const { uri } = asset;
setImageUri(uri);
Cela gère les deux cas de figure d'erreur que je vois le plus souvent. Un sélecteur annulé ne vous donne pas d'actif à lire, et code qui suppose result.assets[0] existe toujours échouera à l'exécution.
Une fois que vous avez l'URI, la mise en prévisualisation est tout à fait simple :
<Image source={{ uri: imageUri }} style={{ width: 240, height: 240 }} />
Si vous prévoyez de télécharger plus tard, gardez l'objet asset entier autour de vous, et non juste l'URI. En pratique, fileName, mimeType, width, heightet fileSize sont souvent utiles pour la validation, la journalisation ou la construction d'une demande multipart plus propre.
Les options qui modifient le comportement ultérieur
Un certain nombre d'options de sélection affectent plus que l'écran de sélection. Elles déterminent la taille du fichier, le comportement d'édition et ce que votre backend doit accepter.
| Option | Type | Ce qu'il change | Utilisation typique |
|---|---|---|---|
mediaTypes |
tableau | Restreint ce que l'utilisateur peut choisir | Limitez la sélection aux images si votre API ne prend en charge que les images |
allowsEditing |
valeur binaire | Laisse l'OS proposer la mise en forme ou l'édition de l'interface utilisateur où cela est pris en charge | Avatars, couvertures carrées, capture de reçus |
quality |
nombre | Comprime les sorties d'images prises en charge | Réduit la taille de téléchargement pour les réseaux mobiles |
base64 |
booléen | Ajoute les données d'image encodées au résultat | Seulement pour les intégrations qui exigent explicitement des données d'image inline |
Un peu de compromis peuvent être faciles à manquer :
allowsEditingest utile lorsque la case d'image a une forme ou une taille fixe. Il est moins utile si votre serveur gère son propre pipeline de mise en forme et que vous souhaitez le fichier original.qualityaffecte le temps de téléchargement, la pression de mémoire et l'espace de stockage du serveur.quality: 1n'est pas automatiquement le choix le plus approprié.mediaTypescorrespond à la règle du serveur. Si le serveur rejette les vidéos, n'obligez pas le sélecteur à les retourner.base64augmente la taille du payload en mémoire. Évitez-le à moins que le service de réception ne le nécessite.
Ce dernier point est important sur les appareils à faible mémoire. Une URI de fichier local est généralement la meilleure remise pour la prévisualisation et l'envoi de fichiers multipart. Le Base64 a des utilisations valides, mais il est coûteux par rapport à passer une référence de fichier.
Base64 versus URI
Pour la plupart des applications, la règle est simple :
- Utilisez URI pour les prévisualisations.
- Utilisez URI pour les envois de fichiers.
- Utilisez base64 seulement lorsque le système récepteur demande explicitement du contenu encodé.
Ce modèle garde le sélecteur code petit et facile à tester. Il s'aligne également sur la façon dont les flux de médias backend sont construits, y compris les services qui publient finalement sur des plateformes externes telles que le publication de médias Instagram API.
Si votre équipe livre des mises à jour OTA fréquentes ou déplace des actifs image lourds à travers la livraison d'applications, les décisions de taille de fichier ici se répercutent dans le reste de la chaîne d'approvisionnement. Ce guide sur l'optimisation des images pour les mises à jour d'applications est un compagnon utile à la configuration du sélecteur.
Un modèle de résultat plus sûr pour les applications réelles
Pour les démos code, stocker uniquement imageUri est suffisant. En production, stockez un objet normalisé afin que l'étape suivante, la prévisualisation, la validation, l'envoi ou la réessai, n'a pas besoin de réinterpréter la réponse brute du sélecteur à chaque fois.
const result = await ImagePicker.launchImageLibraryAsync({
mediaTypes: ['images'],
allowsEditing: true,
quality: 0.8,
});
if (result.canceled || !result.assets?.length) {
return;
}
const asset = result.assets[0];
setSelectedImage({
uri: asset.uri,
fileName: asset.fileName ?? 'upload.jpg',
mimeType: asset.mimeType ?? 'image/jpeg',
width: asset.width,
height: asset.height,
fileSize: asset.fileSize ?? null,
});
Cela vous donne une forme prévisible à l'intérieur de l'application. Il s'agit également de rendre les projets gérés et bare plus faciles à maintenir en alignement car l'application code reste stable tout en travaillant sur les différences natives ailleurs.
Une vérification finale vous aide. N'activez pas les champs de résultat supplémentaires juste au cas où. Demandez les données dont vous avez besoin, et gardez le sélecteur concentré sur la sélection plutôt que de le transformer en une étape de traitement de fichiers général.
Modèles et différences de plateforme avancés
Un composant de sélection se simplifie rarement le moment où la première image sélectionnée doit survivre aux retentatives, aux en-têtes d'authentification, aux différences de permissions natives et à un véritable point de terminaison d'upload. expo-image-picker geste la sélection bien. Le reste de la fonctionnalité est à votre application.

Un modèle d'upload pratique
Pour les APIs qui attendent un téléchargement de fichier, FormData est toujours la valeur de sécurité par défaut. Il fonctionne sur les backends Rails, Node, Laravel, Django et Go courants, et il garde le sélecteur séparé des préoccupations de transport.
async function uploadImage(imageUri: string) {
const formData = new FormData();
formData.append('file', {
uri: imageUri,
name: 'upload.jpg',
type: 'image/jpeg',
} as any);
const response = await fetch('https://your-api.example.com/uploads', {
method: 'POST',
body: formData,
headers: {
Accept: 'application/json',
},
});
if (!response.ok) {
throw new Error('Upload failed');
}
return response.json();
}
That code is enough to prove the path works, but production apps usually need one more layer. Derive name et type du élément sélectionné lorsque possible, attachez l'authentification en dehors de la fonction de sélection, et gardez l'état d'upload séparé de l'état de sélection afin qu'une requête échouée ne force pas l'utilisateur à rouvrir la bibliothèque.
Un ou deux contrôles préviennent les échecs courants que je vois en revue :
- Confirmez le local
uriexiste avant de construire la demande - Afficher une prévisualisation avant l'envoi afin que les utilisateurs détectent le fichier incorrect tôt
- Empêcher les appuis répétés pendant que la demande est en cours de traitement
- Gérer les erreurs de réseau séparément des annulations du sélecteur ou des erreurs de permission
- Attendre que la validation du serveur rejette les fichiers volumineux, les types MIME non pris en charge ou les informations d'authentification manquantes
Si votre serveur exige base64 au lieu de multipart, il s'agit généralement d'une contrainte du serveur et non d'une exigence du sélecteur. Multipart est moins coûteux en mémoire et plus facile à raisonner sur les appareils mobiles.
Lorsque les différences entre les plateformes ont vraiment de l'importance
L'interface utilisateur du sélecteur est native, elle hérite donc du comportement natif. Cela affecte à la fois ce que les utilisateurs voient et ce que votre code devrait supposer.
Sur iOS, les flux d'édition et les invites de permission suivent les conventions d'Apple. L'accès limité aux Photos peut retourner un ensemble d'éléments plus étroit que votre compte de test a vu sur un appareil entièrement autorisé. Sur Android, le comportement du sélecteur varie plus en fonction de la version du système d'exploitation et de la peau du fabricant, notamment autour des albums, des noms de fichiers et de la façon dont les captures de la caméra sont retournées. Les applications React Native nues ressentent ces différences plus directement car vous possédez plus de la mise en place native, mais les applications Expo gérées ont toujours besoin de code qui traite le sélecteur comme plateforme-élastique plutôt que parfaitement uniforme.
La règle pratique est simple. Faites confiance aux champs que vous pouvez valider, et non à une interface utilisateur identique ou à des métadonnées identiques sur les appareils.
Un ou deux exemples sont importants dans les applications réelles :
- L'édition et la mise en forme : Les comportements de l'interface utilisateur et de la récolte ne sont pas identiques entre iOS et Android
- Les métadonnées renvoyées :
fileName,mimeType, etfileSizepeuvent être absents ou incohérents, il faut donc ajouter des valeurs par défaut - Permissions : L'accès aux photos sur iOS peut être limité aux éléments sélectionnés, tandis que le comportement d'Android dépend plus de la version du système d'exploitation et du support du sélecteur système
- Sortie de la caméra : Les images capturées peuvent revenir avec des caractéristiques de nommage, d'orientation ou de compression différentes de celles des actifs de la bibliothèque
Si votre équipe travaille également en dehors d'Expo, ce Guide de développement de l'application DesignStack fournit un contexte Android utile pour les décisions de gestion des médias qui se produisent au-delà d'une seule bibliothèque.
Les différences entre les workflows gérés et non gérés
At ce stade, les choix de mise en place commencent à avoir un impact opérationnel.
Dans le flux de travail géré, les chaînes de permission et la configuration des plugins se trouvent généralement dans la configuration de l'application, et les modifications natives sont appliquées lors de la création d'une nouvelle build. Cela garde la surface de JavaScript propre, mais cela signifie également que la correction d'une configuration n'est pas visible avant la prochaine build native. Les mises à jour OTA ne corrigent pas les permissions natives manquantes.
Dans le flux de travail bare, la même fonctionnalité a plus de composants en mouvement. Vous devez vérifier les descriptions d'utilisation iOS natives, le comportement du manifest Android, l'installation des packages et la synchronisation de la rebuild vous-même. L'avantage est le contrôle. Le coût est que les problèmes de sélection peuvent être causés par la configuration native, et non par le site d'appel JavaScript.
Les équipes qui passent entre Expo et Capacitor surestiment souvent la différence entre ces couches d'abstraction. Capgo a une explication utile de Capacitor sur la façon dont il gère les différences de plateforme how Capacitor handles platform differencesMa préférence est cohérente dans les deux flux de travail. Gardez le sélecteur __CAPGO_KEEP_0__ étroit, normalisez le résultat une fois, envoyez-le à travers une couche dédiée __CAPGO_KEEP_1__ et traitez le comportement spécifique à la plateforme comme quelque chose à configurer et à tester explicitement plutôt que de le lisser avec des hypothèses.
My preference is consistent across both workflows. Keep picker code narrow, normalize the result once, upload through a dedicated API layer, and treat platform-specific behavior as something to configure and test explicitly rather than smooth over with assumptions.
La plupart des bogues de l'Image Picker Expo se répartissent en une petite série de catégories. La solution la plus rapide est généralement d'identifier quel niveau est en panne : la configuration, les permissions, la gestion du résultat ou la mise en page.
__CAPGO_KEEP_0__

Vérifications rapides pour les erreurs courantes
Si le sélecteur ne s'ouvre pas ou si les permissions échouent, vérifiez la mise en place native en premier lieu. Dans les applications bare en particulier, les descriptions d'utilisation iOS manquantes constituent une cause de problème courante.
Si l'application s'effondre après que l'utilisateur a fermé le sélecteur, inspectez vos traitements de résultat. De nombreuses implémentations supposent encore une URI directe et ignorent le canceled Vérification.
Un certain nombre de mappages rapides vous aideront :
- Erreurs de permission refusée : Vérifiez votre configuration d'application et les chaînes de permissions natives, puis rebuild.
undefinedURI de l'image : Lisez à partir deresult.assets?.[0]?.uri, pas deresult.uri.- Rien ne se produit après annulation : Cela peut être correct. Traitez le rejet comme un état sans opération.
- L'image ne s'affiche pas : Confirmez que l'URI a été stockée dans l'état et transmise à
<Image source={{ uri }} />. - La caméra fonctionne de manière étrange dans le simulateur : Testez sur un appareil physique avant de poursuivre une erreur de bibliothèque.
Un court checklist de production
Utilisez cela comme dernier passage avant la livraison :
- Installez avec les outils d'Expo : Utilisez
npx expo install expo-image-picker. - Configurez les pièces natives : Ajoutez le plugin et les descriptions des permissions requises.
- Demandez les permissions intentionnellement : Flux séparé pour la caméra et les bibliothèques multimédias.
- Protéger chaque résultat : Vérifier
result.canceledet lire de manière sécuriséeassets[0]. - Préférez les téléchargements basés sur URI : Conservez base64 uniquement pour les cas spéciaux.
- Tester des appareils réels : Surtout pour la capture de la caméra et les invitations de permission.
Si votre équipe délivre des applications Capacitor ou Electron aux côtés de projets React Native, Capgo est une option pour livrer des mises à jour de JavaScript, CSS, de configuration et d'actifs sans attendre la revue de magasin pour chaque changement. C'est pertinent lorsque des corrections d'image vivent dans votre couche web, telles que l'interface utilisateur de téléchargement, les règles de validation, les copies ou la gestion d'actifs autour du flux de sélection.