Partager une image et du texte dans une app en React Native

Axel de Sainte Marie
4 min readSep 11, 2020

Cela faisait longtemps que je n’avais pas rédigé un petit tuto du vendredi. Après m’être battu avec les fonctionnalités de partage dans une app en cours de développement, je me suis dit qu’un petit billet sur cette problématique pourrait peut-être en aider quelques-uns.

Problématique : être capable de partager un message accompagné d’une photo (ou une photo accompagnée d’un message 😁) depuis une application mobile développée en React Native.

Mon but dans cet article est autant d’apporter un début de réponse, mais également d’ouvrir un échange pour répondre totalement à la problématique. À ce jour, le code exposé ci-dessous, permet d’obtenir les partages suivants :

Résultat des tests

Nous allons utiliser la bibliothèque react-nativ-share développée par React Native Community.

Commençons par installer la bibliothèque

yarn add react-native-share
cd ios && pod install && cd ..

Dans notre application, nous allons ajouter un bouton pour partager les éléments suivant (un peu de pub ne fait jamais de mal 😆) :

  • titre du message (pour les emails) : “OnTheBeach.dev, des applications au top !”
  • message : “Pour développer mes applications mobiles, je fais une confiance aveugle à OnTheBeach.dev”
  • image : https://pbs.twimg.com/media/ETitUA8XgAIulQS.jpg

Voici le code que nous mettons en place en suivant les instructions “par défaut” de la documentation.

import React from 'react';
import { View, Text, TouchableOpacity } from 'react-native';
import Share from 'react-native-share';export default class ShareComponent extends React.Component {
constructor() {
super();
this.shareTheMessage = this.shareTheMessage.bind(this);
}
render() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity
onPress={this.shareTheMessage}
style={{width:200, padding:10, justifyContent: 'center', alignItems: 'center'}} >
<Text style={{textAlign:'center}}>
Partager
</Text>
</TouchableOpacity>
</View>
)
}

shareTheMessage() {
let shareOptions = {
title: “OnTheBeach.dev, des applications au top !”,
message: "Pour développer mes applications mobiles, je fais une confiance aveugle à OnTheBeach.dev",
url: "https://pbs.twimg.com/media/ETitUA8XgAIulQS.jpg"
};
Share.open(shareOptions).then((response) => {
//Gestion du retour
}).catch((error) => {
//Gestion des erreurs
});
}
}

Si vous êtes dans le même cas que le miens, à ce stade là l’objectif n’est pas atteint. Le partage du lien, ne partage que le lien et non l’image directement (s’il n’est pas ignoré dans certain cas).

Pour pouvoir faire un partage qui corresponde à notre objectif, l’idée est de télécharger l’image en local, puis la partager.

Ensuite en fonction des OS, nous n’allons pas utiliser la même méthode de partage. Sur Android, nous allons directement partager le lien locale de l’image. Sur iOS, nous allons partage la version de l’image encodée en Base64.

Une fois le partage terminée, nous supprimerons l’image du stockage local. Pour le téléchargement et l’encodage en Base64, nous utiliserons la bibliothèque react-native-fs.

Si vous ne l’avez pas déjà installée dans votre projet, nous allons le faire.

yarn add react-native-fs
cd ios && pod install && cd ..

Ensuite il nous suffit d’ajouter une étape de téléchargement pour les images, puis d’encodage en Base64 pour iOS. Nous utiliserons la bibliothèque Platform fournie par React Native, pour distinguer les deux méthodes.

import React from 'react';
import { View, Text, TouchableOpacity, Platform } from 'react-native';
import Share from 'react-native-share';
import RNFS from 'react-native-fs';
export default class ShareComponent extends React.Component {
constructor() {
super();
this.shareTheMessage = this.shareTheMessage.bind(this);
this.downloadTheImage = this.downloadTheImage.bind(this);
this.shareWithBase64 = this.shareWithBase64.bind(this);
}
[...]
shareTheMessage() {
let shareOptions = {
title: “OnTheBeach.dev, des applications au top !”,
message: "Pour développer mes applications mobiles, je fais une confiance aveugle à OnTheBeach.dev",
url: "https://pbs.twimg.com/media/ETitUA8XgAIulQS.jpg"
};
this.downloadTheImage(shareOptions);
}
downloadTheImage(shareOptions) {
const pathOfTheImage = `${RNFS.DocumentDirectoryPath}/shareImage.png`;
RNFS.downloadFile({
fromUrl: shareOptions.url,
toFile: pathOfTheImage,
}).promise.then((response) => {
if (Platform.OS === 'android') {
//On partage le fichier local
let localOptions = {...shareOptions};
localOptions.url = pathOfTheImage;
Share.open(shareOptions).then((response) => {
//Gestion du retour
RNFS.unlink(pathOfTheImage);
}).catch((error) => {
//Gestion des erreurs
RNFS.unlink(pathOfTheImage);
});
} else {
this.shareWithBase64(pathOfTheImage, shareOptions);
}
}).catch((error) => {
//En cas d'erreur, on peut choisir une autre option de partage (sans url par exemple)
});
}

shareWithBase64(pathOfTheImage, shareOptions) {
RNFS.readFile(`file://${pathOfTheImage}`, 'base64').then((res) => {
let base64Options = { ...shareOptions };
base64Options.url = `data:image/jpeg;base64,${res}`;
Share.open(shareOptions).then((response) => {
//Gestion du retour
RNFS.unlink(pathOfTheImage);
}).catch((error) => {
//Gestion des erreurs
RNFS.unlink(pathOfTheImage);
});
})
}
}

Et voilà un partage plus efficace et adapté aux OS.

--

--

Axel de Sainte Marie

Show Runner de projets mobiles. Développeur React Native et passionné par les challenges du monde mobile.