Skip to main content

How To Define a Portal APIs

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, this step is not needed, 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.

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

In iOS, if you require Objective-C compatibility, you'll also need a file called EchoPlugin.m to create Objective-C bindings with helper functions that Capacitor provides. Below is what the EchoPlugin Objective-C bindings would look like.

EchoPlugin.m
#import <Capacitor/Capacitor.h>
CAP_PLUGIN(ECHO_PLUGIN, "EchoPlugin",  CAP_PLUGIN_METHOD(echo, CAPPluginReturnNone);)

Adding the Plugin to the Portal#

Once the Capacitor Plugin has been created, its time to add it to the Portal for usage.

Android#

When creating a Portal via the PortalManager, you'll need to call the PortalManager.addPlugin() function in order to add the Plugin to that Portal instance.

PortalManager.newPortal("echo_portal")    .addPlugin(EchoPlugin::class.java)    .create()

iOS#

After a Portal has loaded, you will need to inject the Plugin to the Portal's bridge. You can do this in the viewDidLoad function.

override func viewDidLoad() {    // Inject the plugin into the native bridge    apiPlugin = bridge?.plugin(withName: "EchoPlugin") as? EchoPlugin        // now call super which will start the initial load    super.viewDidLoad()    }

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 using the Capacitor.registerPlugin() function. From there, 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 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.