Gaurav Roy
Gaurav Roy

Reputation: 12210

RN fetch blob download docx or pdf from URL in IOS

What is done:

Implemented in Android and its getting downloaded in specific DCIM directory in android. In ios using DocumentDir to download the pdf or docx file. Using "rn-fetch-blob": "^0.12.0";

Error:

In IOS it says the message in console :

The file saved to /var/mobile/Containers/Data/Application/E6FDC2DD-7FCA-44DC-85C4-A275078F8825/Documents/wow13.pdf

The code to download is something like this :

downloadFileOnSuccess = async () => {
    let dirs =
      Platform.OS == 'ios'
        ? RNFetchBlob.fs.dirs.DocumentDir
        : RNFetchBlob.fs.dirs.DCIMDir;
    console.log(dirs, 'document path');
    RNFetchBlob.config({
      // response data will be saved to this path if it has access right.

      fileCache: true,
      path: dirs + `/wow13.pdf`,
    })
      .fetch(
        'GET',
        'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
        {
          //some headers ..
        },
      )
      .then(res => {
        // the path should be dirs.DocumentDir + 'path-to-file.anything'
        console.log('The file saved to ', res.path());
      });
  };

But i cannot get where the file is downloaded in my iphone 7 real device. Is there any permission i'm missing in IOS? Havent added any permission for IOS.

Upvotes: 11

Views: 30314

Answers (6)

Manish Singh Chouhan
Manish Singh Chouhan

Reputation: 381

I used this in my File. I used the code to share the file and it works do download it from the Save to File option. enter image description here

onClickFileDownload = async () => {
    const saveDir = Platform.OS == 'ios' ? `${RNFetchBlob.fs.dirs.DocumentDir}` : `${RNFetchBlob.fs.dirs.DownloadDir}`;
   
    const configfb = {
    fileCache: true,
    useDownloadManager: true,
    notification: true,
    mediaScannable: true,
    title: 'pdfInfo.pdf',
    path: `${saveDir}/` + `${Platform.OS==='ios'?this.state.certificateMetaData?.user_name:this.state.certificateMetaData?.user_name+".pdf"}`,
}

    const configOptions = Platform.select({
      ios: {
          fileCache: configfb.fileCache,
          title: configfb.title,
          path: configfb.path,
          appendExt: 'pdf',
      },
      android: configfb,
  });

    
     await RNFetchBlob.config(
      configOptions
                  ) .fetch('GET', `${this.state.catificationData.attributes?.document}`) 
                  .then((res) => { 
                      if (Platform.OS === 'ios') 
                      {
                          RNFetchBlob.ios.openDocument(res.data);
                 
const filePath = `${res.data}`;

          let options = {
            type: 'application/pdf',
            url: `${filePath}.pdf`,
            saveToFiles: true,
          };

            Share.share(options)
            .then((resp) => console.log("then --> ",resp))
            .catch((err) => console.log("catch --> ",err));

                          if(res.respInfo.status==200 && Platform.OS != 'ios'){
                            
                              Alert.alert("File Downloaded Succesfully")
                            }
                           return true; 
                          } else { 
                              console.log('The file saved to android ', res.path()); return true; 
                          } }) .catch((err) => 
                          { 
                          return true; 
    }); 
        
  }

Upvotes: 0

Shivo'ham
Shivo'ham

Reputation: 3062

Worked for me using react native Share

const downloadFile = (fileName) => {
    const source = "sample.pdf";
    const { dirs } = RNFetchBlob.fs;
    RNFetchBlob.config({
      fileCache: true,
      appendExt: 'pdf',
      path: `${dirs.DocumentDir}/${fileName}`,
      addAndroidDownloads: {
        useDownloadManager: true,
        notification: true,
        title: fileName,
        description: 'File downloaded by download manager.',
        mime: 'application/pdf',
      },
    })
      .fetch('GET', source)
      .then((res) => {
        // in iOS, we want to save our files by opening up the saveToFiles bottom sheet action.
        // whereas in Android, the download manager is handling the download for us.
        if (Platform.OS === 'ios') {
          const filePath = res.path();
          let options = {
            type: 'application/pdf',
            url: filePath,
            saveToFiles: true,
          };
          Share.open(options)
            .then((resp) => console.log(resp))
            .catch((err) => console.log(err));
        }
      })
      .catch((err) => console.log('BLOB ERROR -> ', err));
  };

Upvotes: 0

GhostMode
GhostMode

Reputation: 45

Improving on Ajmall Hasan's answer.
I have to change ${pdfInfo.pdf} to ${'pdfInfo.pdf'} to make it work

const actualDownload = () => {
        const { dirs } = RNFetchBlob.fs;
        const dirToSave = Platform.OS == 'ios' ? dirs.DocumentDir : dirs.DownloadDir
        const configfb = {
            fileCache: true,
            useDownloadManager: true,
            notification: true,
            mediaScannable: true,
            title: pdfInfo.pdf,
            path: `${dirToSave}/${'pdfInfo.pdf'}`,
        }
        const configOptions = Platform.select({
            ios: {
                fileCache: configfb.fileCache,
                title: configfb.title,
                path: configfb.path,
                appendExt: 'pdf',
            },
            android: configfb,
        });
    
        console.log('The file saved to ', configfb, dirs);
    
        RNFetchBlob.config(configOptions)
            .fetch('GET', `https://aquatherm.s3.ap-south-1.amazonaws.com/pdfs/${'pdfInfo.pdf'}`, {})
            .then((res) => {
                if (Platform.OS === "ios") {
                    RNFetchBlob.fs.writeFile(configfb.path, res.data, 'base64');
                    RNFetchBlob.ios.previewDocument(configfb.path);
                }
                if (Platform.OS == 'android') {
                    showSnackbar('File downloaded');
                }
                console.log('The file saved to ', res);
            })
            .catch((e) => {
                showSnackbar(e.message);
                console.log('The file saved to ERROR', e.message)
            });
    }

Upvotes: 3

GUGAN RAJ
GUGAN RAJ

Reputation: 111

 GetItem_downloadbtn = (item, itemname) => {
var pdfInfo = itemname;
const { dirs } = RNFetchBlob.fs;
const dirToSave = Platform.OS == 'ios' ? dirs.DocumentDir : dirs.DownloadDir
const configfb = {
    fileCache: true,
    useDownloadManager: true,
    notification: true,
    mediaScannable: true,
    title: pdfInfo.pdf,
    path: `${dirToSave}/${itemname}`,
}
const configOptions = Platform.select({
    ios: {
        fileCache: configfb.fileCache,
        title: configfb.title,
        path: configfb.path,
        appendExt: 'pdf',
    },
    android: configfb,
});
console.log('The file saved to 23233', configfb, dirs);

RNFetchBlob.config(configOptions)
    .fetch('GET', item, {})
    .then((res) => {
        if (Platform.OS === "ios") {
            RNFetchBlob.fs.writeFile(configfb.path, res.data, 'base64');
            RNFetchBlob.ios.previewDocument(configfb.path);
        }
        setisdownloaded(false)
        if (Platform.OS == 'android') {
            showSnackbar('File downloaded');
        }
        console.log('The file saved to ', res);
    })
    .catch((e) => {
        setisdownloaded(true)
        showSnackbar(e.message);
        console.log('The file saved to ERROR', e.message)
    });

}

Upvotes: 0

Gaurav Roy
Gaurav Roy

Reputation: 12210

Thanks to pruthvi, i got the answer , for ios i need to prompt the user:

.then(resp => {
      if (Platform.OS === "ios") {
        RNFetchBlob.ios.openDocument(resp.data);
      }
    })

hope it helps you guys

Upvotes: 12

Ajmal Hasan
Ajmal Hasan

Reputation: 1569

Latest working solution:

const actualDownload = () => {
        const { dirs } = RNFetchBlob.fs;
        const dirToSave = Platform.OS == 'ios' ? dirs.DocumentDir : dirs.DownloadDir
        const configfb = {
            fileCache: true,
            useDownloadManager: true,
            notification: true,
            mediaScannable: true,
            title: pdfInfo.pdf,
            path: `${dirToSave}/${pdfInfo.pdf}`,
        }
        const configOptions = Platform.select({
            ios: {
                fileCache: configfb.fileCache,
                title: configfb.title,
                path: configfb.path,
                appendExt: 'pdf',
            },
            android: configfb,
        });
    
        console.log('The file saved to 23233', configfb, dirs);
    
        RNFetchBlob.config(configOptions)
            .fetch('GET', `https://aquatherm.s3.ap-south-1.amazonaws.com/pdfs/${pdfInfo.pdf}`, {})
            .then((res) => {
                if (Platform.OS === "ios") {
                    RNFetchBlob.fs.writeFile(configfb.path, res.data, 'base64');
                    RNFetchBlob.ios.previewDocument(configfb.path);
                }
                setisdownloaded(false)
                if (Platform.OS == 'android') {
                    showSnackbar('File downloaded');
                }
                console.log('The file saved to ', res);
            })
            .catch((e) => {
                setisdownloaded(true)
                showSnackbar(e.message);
                console.log('The file saved to ERROR', e.message)
            });
    }

Upvotes: 10

Related Questions