Skip to main content

How To Define a Portal API

One of the biggest benefits of including Ionic Portals in an application is the ability to easily communicate between web and native code using the PortalsPlugin. However, in some more niche cases, creating your own Plugins may be neccessary. By creating a Capacitor Plugin, you can create your own API to communicate between web and native code.

For this example, we will create a Plugin called EchoPlugin that has a single function: echo.

Creating API Definitions

We strongly recommend using TypeScript to create a type defintion file which can be used to define your API. This way, there is a central source of truth for the API across Android and iOS as well as having type defintions for the web code.

export interface EchoPlugin {
echo(options: { value: string }): Promise<{ value: string }>;
}

On the Android or iOS side, the EchoPlugin class will need to match this type signature.

info

If you are not using TypeScript, you can skip this step, but you'll need to take steps to make sure that the method signatures across Android and iOS match if you are using reusing Portals across multiple mobile applications.

Implementing the API

First, you'll need to install the proper dependencies. You can now start building the plugin. In this example, the EchoPlugin will extend the base Capacitor Plugin class and implement the API that was defined in the previous step.

import Capacitor

@objc(MYYEchoPlugin)
public class EchoPlugin: CAPPlugin {
@objc func echo(_ call: CAPPluginCall) {
let value = call.getString("value");
print(value);
}
}
info

You'll also need a file called EchoPlugin.m to create Objective-C bindings through helper macros that Capacitor provides. Below is an example of EchoPlugin Objective-C bindings.

#import <Capacitor/Capacitor.h>

CAP_PLUGIN(ECHO_PLUGIN, "EchoPlugin",
CAP_PLUGIN_METHOD(echo, CAPPluginReturnNone);
)

Adding the Plugin to the Portal

After creating the Capacitor Plugin, add the Plugin to the Portal to use it.

You will need to add the classpath to your custom plugin for Android and the Objective-C class name for iOS (the name provided in the @objc annotation in the example above):

import { addPortal } from "@ionic/portals-react-native";

const echoPortal = {
name: "echoPortal",
plugins: [
{
androidClassPath: "com.myapplication.echo.EchoPlugin",
iosClassName: "MYYEchoPlugin"
}
]
};

addPortal(echoPortal);

Calling Your Plugin Code via the Web

Once the Plugin has been defined, implemented, and initialized in the native code, you will need to register the Plugin on the web. To do this, you can use the Capacitor.registerPlugin() function. After calling this function, Capacitor will handle communication across native and web code.

import { registerPlugin } from "@capacitor/core";
import { EchoPlugin } from "./types";

const Plugin = registerPlugin<EchoPlugin>("EchoPlugin");
export default Plugin;

Once the Plugin has been registered in the web code, you can use it anywhere in your codebase without needing to register it again in the web code.

import EchoPlugin from "./echo-plugin";

EchoPlugin.echo("Hello World!");

Note

For more information on how to create Capacitor Plugins, check our guide for creating Capacitor Plugins.