Save a file to device folder (like "Download")

I’ve found out how to save mp3/mp4 files.

On iOS instead of using the MediaLibrary for these files (at the moment MediaLibrary only accepts images on iOS), one should use Sharing.shareAsync(url, options) from the expo-sharing library.

Here’s some rough code which can work to handle mp3/mp4 files on iOS (with a little creativity you can support all audio/video files on iOS this way as well):

const ios = Platform.OS === 'ios'

try {
        const res = await FileSystem.downloadAsync(uri, fileUri)
        if (ios) {
            if (fileUri.endsWith('mp3')) {
                const shareResult = await Sharing.shareAsync(fileUri, { UTI: 'public.audio' });
                return;
            } else if (fileUri.endsWith('mp4')) {
                const shareResult = await Sharing.shareAsync(fileUri, { UTI: 'public.movie' });
                return;
            }
        }
        saveFile(res.uri)
}

For the UTI option I also found public.mp3 and public.mp4 to work as well. This will trigger a popup from the system that allows the user to choose to save the file to their device and to choose the folder where they want to save the file to (I tested this on an iPad running iOS 14.1).

Note that this method makes it not very useful to specify the folder to download the file to (as the user in the end chooses the folder they wish to download the file to). It also does not work if the user leaves the app while the file is downloading (because the share prompt is not accessible outside the app). Things to keep in mind while developing.

I’m going to work on adding this to expo-file-dl. Did you find the README there not to be helpful? There’s also example code which shows how to use the expo-file-dl package here: expo-file-dl-example