Native file viewer for react-native - now with TurboModules support
npm install react-native-file-viewer-turboSince the original react-native-file-viewer is no longer maintained, I decided to fork it and update it to work with the latest React Native versions.
This native file viewer for React Native utilizes the QuickLook Framework on iOS and the ACTION_VIEW intent to launch the default app associated with the specified file on Android. It now features TurboModules and Expo support.
Starting from version 0.7.0, this library supports only the New Architecture. If you need to support the Old Architecture, please use version 0.6.x or earlier.
While most of the code remains the same as the original library, I implemented several changes to enhance the overall UI/UX and ensure proper handling of asynchronous logic by using promises instead of EventEmitters where applicable.
``sh`
npx expo install react-native-file-viewer-turbo
Add plugin to your app.json or app.config.js with preferred mimeTypes (it will modify AndroidManifest.xml as described below in extra step for Android section):
`json`
{
"plugins": [
[
"react-native-file-viewer-turbo",
{
"mimeTypes": [
"/"
]
}
]
]
}
`sh
npm install react-native-file-viewer-turbo
OR
yarn add react-native-file-viewer-turbo
cd ios && pod install
`
#### Extra step (Android only)
If your app is targeting Android 11 (API level 30) or newer, the following extra step is required, as described in Declaring package visibility needs and Package visibility in Android 11.
Specifically:
> If your app targets Android 11 or higher and needs to interact with apps other than the ones that are visible automatically, add the
For example, if you know upfront that your app is supposed to open PDF files, the following lines should be added to your AndroidManifest.xml.
`diff`
...
+
+
+
+
+
+
+
| Parameter | Type | Description |
| ---------------------- | ------ |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| filepath | string | The absolute path where the file is stored. The file needs to have a valid extension to be successfully detected. Use expo-file-system constants to determine the absolute path correctly. |
| options (optional) | Object | Some options to customize the behaviour. See below. |
#### Options
| Parameter | Type | Platform | Description |
|-----------------------------------|---------------|--------------|--------------------------------------------------------------------------------------------------|
| displayName (optional) | string | iOS | Customize the QuickLook title |
| doneButtonTitle (optional) | string | iOS | Customize UINavigationController Done button title |
| doneButtonPosition (optional) | left \| right | iOS | Customize UINavigationController Done button position |
| onDismiss (optional) | function | iOS, Android | Callback invoked when the viewer is being dismissed |
| showOpenWithDialog (optional) | boolean | Android | If there is more than one app that can open the file, show an _Open With_ dialogue box |
| showAppsSuggestions (optional) | boolean | Android | If there is not an installed app that can open the file, open the Play Store with suggested apps |
IMPORTANT: Try to be as granular as possible when defining your own queries. This might affect your Play Store approval, as mentioned in Package visibility filtering on Android.
> If you publish your app on Google Play, your app's use of this permission is subject to approval based on an upcoming policy.
`javascript
import { open } from "react-native-file-viewer-turbo";
try {
await open(path); //absolute-path-to-my-local-file
} catch (e) {
// error
}
`
`javascript
import { open } from "react-native-file-viewer-turbo";
import { getDocumentAsync } from "expo-document-picker";
try {
const result = await getDocumentAsync({ type: 'application/pdf' });
if (result.canceled || !result.assets?.[0]) {
return;
}
await open(result.assets[0].uri, { displayName: 'My PDF Document' });
} catch (e) {
// error
}
`
`javascript
import { open } from "react-native-file-viewer-turbo";
import { launchImageLibraryAsync } from "expo-image-picker";
try {
const result = await launchImageLibraryAsync();
if (result.canceled || !result.assets?.[0]) {
return;
}
await open(result.assets[0].uri, { displayName: 'Image' });
} catch (e) {
// error
}
`
`javascript
import { open } from "react-native-file-viewer-turbo";
try {
await open(path, { showOpenWithDialog: true }) // absolute-path-to-my-local-file.
} catch (e) {
// error
}
`
Since the library works only with absolute paths and Android assets folder doesn't have any absolute path, the file needs to be copied first. Use expo-file-system.
Example (using expo-file-system):
`javascript
import { open } from "react-native-file-viewer-turbo";
import { File, Paths } from "expo-file-system/next";
const fileName = "file-to-open.doc";
const sourceFile = new File(Paths.cache, fileName);
const destFile = new File(Paths.document, fileName);
sourceFile.copy(destFile);
await open(destFile.uri, { displayName: 'My Document' });
`
No function about file downloading has been implemented in this package.
Use expo-file-system or any similar library for this purpose.
Example (using expo-file-system):
`javascript
import { open } from "react-native-file-viewer-turbo";
import { File, Paths } from "expo-file-system/next";
const url =
"https://github.com/Vadko/react-native-file-viewer-turbo/raw/main/docs/sample.pdf";
// IMPORTANT: The correct file extension is always required.
// You might encounter issues if the file's extension isn't included
// or if it doesn't match the mime type of the file.
// https://stackoverflow.com/a/47767860
function getUrlExtension(url: string) {
return url.split(/[#?]/)[0].split(".").pop()?.trim() ?? "";
}
const extension = getUrlExtension(url);
try {
const destination = new File(Paths.document, temporaryfile.${extension});
// Delete existing file if exists
if (destination.exists) {
destination.delete();
}
await File.downloadFileAsync(url, destination);
await open(destination.uri, { displayName: "Downloaded PDF" });
} catch (e) {
// error
}
``
See the contributing guide to learn how to contribute to the repository and the development workflow.
MIT
---
Made with create-react-native-library