loading...
Cover image for How To Use Ionic Native Plugins In React Capacitor Mobile Application
Ionic

How To Use Ionic Native Plugins In React Capacitor Mobile Application

aaronksaunders profile image Aaron K Saunders ・3 min read

When working with Ionic Capacitor it is recommended to use the Capacitor Plugins sometimes you need to use a cordova or ionic-native plugin to get the job done. In the example below we show a quick use case of using the Ionic Native FileTransfer Plugin.

The basic command line to get your app started

npm install -g @ionic/cli
ionic start myApp blank --type react

The rest will take awhile

Aarons-iMac:reactjs aaronksaunders$ ionic start myAppEmpty blank --type react
✔ Preparing directory ./myAppEmpty - done!
✔ Downloading and extracting blank starter - done!
? Integrate your new app with Capacitor to target native iOS and Android? Yes
> ionic integrations enable capacitor --quiet -- myAppEmpty io.ionic.starter
> npm i --save -E @capacitor/core
npm notice created a lockfile as package-lock.json. You should commit this file.
+ @capacitor/core@1.5.1
added 2 packages from 2 contributors and audited 2 packages in 0.979s
found 0 vulnerabilities

> npm i -D -E @capacitor/cli
+ @capacitor/cli@1.5.1
added 56 packages from 90 contributors and audited 87 packages in 10.059s
found 0 vulnerabilities

> capacitor init myAppEmpty io.ionic.starter --web-dir build --npm-client npm


🎉   Your Capacitor project is ready to go!  🎉

Add platforms using "npx cap add":

  npx cap add android
  npx cap add ios
  npx cap add electron

Follow the Developer Workflow guide to get building:
https://capacitor.ionicframework.com/docs/basics/workflow

[OK] Integration capacitor added!

To get started, make sure you are properly installing the required plugins

npm install cordova-plugin-file-transfer
npm install @ionic-native/file-transfer
npm install cordova-plugin-file
npm install @ionic-native/file
npm install @ionic-native/core

In your code you will import the libraries need

import {
  FileTransfer,
  FileUploadOptions,
  FileTransferObject
} from "@ionic-native/file-transfer";
import { File } from "@ionic-native/file";
import { Capacitor } from '@capacitor/core';

Finally when accessing the objects most of them now have a create method that exists so for example creating the file transfer object.

let fileTransfer = FileTransfer.create();

So putting it all together you get a functional component that looks something like this as the main function for downloading the image.

There are potential permission issues when accessing the image url to render so we convert it using the function convertFileSrc which is available as part of @capacitor/core so be sure to import it.

  const [theImage, setImage] = React.useState<string|undefined>();

  const download = () => {
    console.log("download");
    let fileTransfer = FileTransfer.create();
    const url = "https://www.postfun.com/wp-content/uploads/2019/09/Hickory-horned-devil-82819.jpg";
    fileTransfer.download(url, File.tempDirectory + "file.jpg", true).then(
      async entry => {

        console.log("download complete: " + entry.toURL());

        // need to convert url so you don't get permission errors...
        setImage(Capacitor.convertFileSrc(File.tempDirectory + "file.jpg"))
      },
      error => {
        // handle error
        console.log("error", error);
      }
    );
  };

the render section of the component, where on the click event of the download button we call the download function.

We using the IonImg tag to render the actual image and IonLabel to display the local path

return (
  <IonPage>
    <IonHeader>
      <IonToolbar>
        <IonTitle>Capacitor React</IonTitle>
      </IonToolbar>
    </IonHeader>
    <IonContent className="ion-padding">
      <IonToolbar>
        <h2>FileTransfer Plugin Test</h2>
      </IonToolbar>
      <IonImg src={theImage}></IonImg>
      <IonItem className="ion-text-wrap">
        <IonLabel>{theImage}</IonLabel>
      </IonItem>
      <div>
        <IonButton onClick={() => download()}>DOWNLOAD</IonButton>
      </div>
    </IonContent>
  </IonPage>
);


Since I am using IOS, to get capacitor app running in the simulator...

ionic build <- only needed first time
ionic cap sync ios
ionic cap open ios

If you see this error on IOS

*** NSForwarding: warning: object 0x7fff89115030 of class
 'PFEmbeddedMulticasterImplementation' does not implement 
doesNotRecognizeSelector: -- abort

Then you will need to update capacitor to latest version

npm install @capacitor/ios@next

Conclusion

In this post I've gone over using reactjs and with Ionic Capacitor and the cordova plugins. There are a lot of examples out there using angular code with the Ionic Native, that can be translated to use in react, but I figured I would add one that is just based on react from the start

Code for this article is here

Discussion

pic
Editor guide
Collapse
shaneparsons profile image
Shane Parsons

Thank you for detailing what to do in the event of a PFEmbeddedMulticasterImplementation error!

I wasn't actually following this tutorial, but I ran into that error while developing an angular / capacitor app (after updating xcode?) and had no idea what to do. Thankfully the keyword PFEmbeddedMulticasterImplementation brought me here!

Collapse
aaronksaunders profile image
Aaron K Saunders Author

Thanks for stopping by either way, glad I was able to help

Collapse
eichgi profile image
Hiram

I am experiencing this issue:

error FileTransferError {code: 3, source: "postfun.com/wp-content/uploads/201...", target: "file:///android_asset/file.jpg", http_status: 401, body: null, …}

Do you have an idea why?

the following is my code:

download() {
      console.log("download");
      let fileTransfer = FileTransfer.create();
      const url = "https://www.postfun.com/wp-content/uploads/2019/09/Hickory-horned-devil-82819.jpg";
      fileTransfer.download(url, File.applicationDirectory + "file.jpg", true, {mode: 'no-cors'})
          .then(async entry => {
                console.log("download complete: " + entry.toURL());
                // need to convert url so you don't get permission errors...
                this.image = (Capacitor.convertFileSrc(File.tempDirectory + "file.jpg"));
              },
              error => {
                // handle error
                console.log("error", error);
              })
          .catch(error => {
            console.log("ERROR: ", error);
          });
    },
Enter fullscreen mode Exit fullscreen mode