Solución:
De acuerdo, para las generaciones futuras, así es como resolví este problema:
Actualizado el 13 de septiembre de 2017:
Hay un nuevo módulo de NPM que hace que todo este proceso sea mucho más fácil. Sugeriría usarlo en el futuro en lugar de mi respuesta original a continuación:
react-native-pdf
Una vez instalado, renderizar el PDF es tan fácil como esto:
export default class YourClass extends Component {
constructor(props) {
super(props);
this.pdf = null;
}
render() {
let yourPDFURI = {uri:'bundle-assets://pdf/YourPDF.pdf', cache: true};
return <View style={{flex: 1}}>
<Pdf ref={(pdf)=>{this.pdf = pdf;}}
source={yourPDFURI}
style={{flex: 1}}
onError={(error)=>{console.log(error);}} />
</View>
}
}
Simplemente coloque su pdf real en el android/app/src/main/assets/pdf
carpeta de su proyecto.
Respuesta original:
iOS
render: function() {
return <WebView source={{uri: 'My.pdf'}}/>
}
El truco es que debes incluir My.pdf
en su proyecto en Xcode y asegúrese de que se agregue a su objetivo de compilación.
Simplemente copiarlo en la carpeta de su proyecto React Native no fue suficiente. Tenía que ser parte del propio proyecto Xcode.
Androide
Parece que Android no proporcionó un visor de PDF nativo hasta 5.0 (Lollipop). Para solucionar esto, tuve que hacer uso de tres técnicas clave:
- Extraiga el PDF de mi paquete de APK y guárdelo en el
files
carpeta de mi aplicación. Esta respuesta SO fue muy útil para lograr esto:
Android: ¿Cómo copiar archivos de la carpeta ‘activos’ a la tarjeta SD?
Modifiqué un poco el código para que el archivo no fuera a un sdcard
pero a mi aplicación files
carpeta. Esto es lo que agregué a mi MainActivity.java
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AssetManager assetManager = getAssets();
String[] files = null;
try {
files = assetManager.list("pdf");
} catch (IOException e) {
Log.e("tag", "Failed to get asset file list.", e);
}
if (files != null) for (String filename : files) {
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open("pdf/" + filename);
File outFile = new File(getFilesDir(), filename);
out = new FileOutputStream(outFile);
copyFile(in, out);
Log.e("tag", "Copy was a success: " + outFile.getPath());
} catch(IOException e) {
Log.e("tag", "Failed to copy asset file: " + "pdf/" + filename, e);
}
finally {
if (in != null) {
try {
in.close();
} catch (IOException e) {
// NOOP
}
}
if (out != null) {
try {
out.close();
} catch (IOException e) {
// NOOP
}
}
}
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}
También me aseguré de que mi PDF esté en el assets/pdf
carpeta debajo android/app/src/main
-
Luego utilicé el paquete react-native-fs para obtener la URL absoluta de mi PDF, que ahora está en el
files
carpeta:var RNFS = require('react-native-fs'); var absolutePath = RNFS.DocumentDirectoryPath + '/My.pdf';
-
Con todo esto en su lugar, utilicé react-native-pdf-view para cargar y mostrar el PDF:
import PDFView from 'react-native-pdf-view'; render: function() { var absolutePath = RNFS.DocumentDirectoryPath + '/My.pdf'; return <PDFView ref={(pdf)=>{this.pdfView = pdf;}} src={absolutePath} style={ActharStyles.fullCover} /> }
¡Buena suerte!
Una solución simple para este problema es establecer <WebView>
source/uri
a esto:
https://drive.google.com/viewerng/viewer?embedded=true&url={your pdf url}’