React Native course ยท Module 6: Photos, camera and audio
expo-file-system and expo-sharing
In this lesson3
Manage files and share them!
expo-file-system
npx expo install expo-file-systemimport * as FileSystem from 'expo-file-system';
// Directory paths
const documentsDir = FileSystem.documentDirectory;
const cacheDir = FileSystem.cacheDirectory;
// Downloading a file
async function downloadImage(url: string, filename: string) {
const fileUri = `${FileSystem.documentDirectory}${filename}`;
const downloadResumable = FileSystem.createDownloadResumable(
url,
fileUri,
{},
(progress) => {
const percent = progress.totalBytesWritten / progress.totalBytesExpectedToWrite;
console.log(`Downloaded: ${Math.round(percent * 100)}%`);
}
);
const result = await downloadResumable.downloadAsync();
return result?.uri;
}
// Reading a file
async function readFile(filename: string) {
const fileUri = `${FileSystem.documentDirectory}${filename}`;
const content = await FileSystem.readAsStringAsync(fileUri);
return content;
}
// Writing a file
async function writeFile(filename: string, content: string) {
const fileUri = `${FileSystem.documentDirectory}${filename}`;
await FileSystem.writeAsStringAsync(fileUri, content);
}
// File info
async function getFileInfo(uri: string) {
const info = await FileSystem.getInfoAsync(uri);
console.log('Exists:', info.exists);
console.log('Size:', info.size);
console.log('URI:', info.uri);
return info;
}
// Deleting
async function deleteFile(uri: string) {
await FileSystem.deleteAsync(uri);
}
// Listing files
async function listDirectory(dir: string) {
const files = await FileSystem.readDirectoryAsync(dir);
return files;
}expo-sharing
npx expo install expo-sharingimport * as Sharing from 'expo-sharing';
import * as FileSystem from 'expo-file-system';
async function shareImage(imageUri: string) {
// Check if sharing is available
const isAvailable = await Sharing.isAvailableAsync();
if (!isAvailable) {
Alert.alert('Error', 'Sharing is not available on this device');
return;
}
// Share
await Sharing.shareAsync(imageUri, {
mimeType: 'image/jpeg',
dialogTitle: 'Share photo',
});
}
// Sharing from a downloaded URL
async function downloadAndShare(url: string) {
const filename = url.split('/').pop() || 'file';
const localUri = `${FileSystem.cacheDirectory}${filename}`;
// Download
await FileSystem.downloadAsync(url, localUri);
// Share
await Sharing.shareAsync(localUri);
}expo-media-library
npx expo install expo-media-libraryimport * as MediaLibrary from 'expo-media-library';
// Save to gallery
async function saveToGallery(uri: string) {
const { status } = await MediaLibrary.requestPermissionsAsync();
if (status !== 'granted') return;
const asset = await MediaLibrary.createAssetAsync(uri);
// Optionally: add to album
const album = await MediaLibrary.getAlbumAsync('Atlantis');
if (album) {
await MediaLibrary.addAssetsToAlbumAsync([asset], album, false);
} else {
await MediaLibrary.createAlbumAsync('Atlantis', asset, false);
}
Alert.alert('Success', 'Photo saved to gallery!');
}
// Get photos from gallery
async function getPhotos() {
const { status } = await MediaLibrary.requestPermissionsAsync();
if (status !== 'granted') return [];
const media = await MediaLibrary.getAssetsAsync({
mediaType: 'photo',
first: 20,
sortBy: MediaLibrary.SortBy.creationTime,
});
return media.assets;
}These libraries give you full control over files and media!
Code for this lesson: App.tsx
import React, { useState } from 'react';
import { View, Text, Pressable, StyleSheet, Alert } from 'react-native';
import * as FileSystem from 'expo-file-system';
import * as Sharing from 'expo-sharing';
export default function App() {
const [busy, setBusy] = useState(false);
const downloadAndShare = async () => {
setBusy(true);
const url = 'https://picsum.photos/600';
const fileUri = `${FileSystem.cacheDirectory}atlantis.jpg`;
// TODO: download the file from the URL to fileUri:
// await FileSystem.downloadAsync(url, fileUri);
// TODO: check sharing availability:
// const isAvailable = await Sharing.isAvailableAsync();
// if (!isAvailable) { Alert.alert('Error', 'Sharing not available'); return; }
// TODO: share the downloaded file:
// await Sharing.shareAsync(fileUri);
setBusy(false);
};
return (
<View style={styles.container}>
<Pressable style={styles.button} onPress={downloadAndShare} disabled={busy}>
<Text style={styles.buttonText}>{busy ? 'Downloading...' : 'Download & share'}</Text>
</Pressable>
</View>
);
}
const styles = StyleSheet.create({
container: { flex: 1, justifyContent: 'center', alignItems: 'center', backgroundColor: '#1a5276' },
button: { backgroundColor: '#2980b9', paddingVertical: 14, paddingHorizontal: 32, borderRadius: 8 },
buttonText: { color: '#fff', fontSize: 16, fontWeight: '600' },
});Docs entries used in this lesson
Spotted a mistake in this lesson?
Check yourself
Answer the questions from this lesson. Pick an answer to see right away whether it is correct.
1. Where should you store persistent application files?
Hands-on tasks in the game
- Horizontal ordering
Arrange file sharing:
- Code editor
Complete the code with FileSystem and Sharing.