Creating an API bridge Between the Cordova plugin and Windows
To use a Cordova plugin in the Custom SAP Fiori Client for Windows 10, you must create an API bridge between the plugin and the Custom Fiori Client for Windows 10.
On Windows, a Cordova app is basically an HTML5 application. As a result, there is no native side to an application and nothing runs below the index.html layer. Windowsspecific code in plugins is written in JavaScript and initialized alongside the cross-platform JavaScript APIs as proxy APIs.
Architecture
For the SAP Fiori Client, the index.html page is the native side container. It includes cordova.js and initializes Cordova plugins. There is a webview element (x-ms-webview) inside index.html, which opens the remote Fiori application.
The index.html page and the remote Fiori Application (a web page inside the webview) are two completely different contexts, with different DOMs and "window" objects. One cannot reach the other's namespaces. As a result, the previously initialized plugins in the local context cannot be reached directly from the webview.
This issue is solved on other platforms by injecting cordova.js into the remote web page (opened in the main native webview), initializing JavaScript Cordova APIs, and gaining access to the native side that has already been initialized.
Injecting Cordova into the remote Fiori App is impossible on Windows because remote pages are not allowed access to certain Windows APIs for security reasons. This means that Fiori Applications cannot access any Cordova plugins.
API Bridge
Instead of injecting cordova.js, API calls must be between the remote context and the local context.
Communication between these two contexts is handled using a mock API for each supported plugin, which is then injected into the Fiori App. Calling these APIs notifies the local context through a bridge. The local index.html can then access the actual plugin APIs, call them, and return the results to the Fiori App.
- The Fiori App is opened inside the webview.
- An iframe is injected into the webview, which opens the empty becon.html local file.
- Local context subscribes to navigation events of this iframe.
- Mocked-up Kapsel APIs are injected into the webview.
- Calls to Kapsel APIs from the remote context trigger a bridge.
- The bridge stringifies information (the exact method that was called and the parameters) and stores the callbacks, all in the remote context.
- The bridge navigates becon.html using a hashtag, and pastes the stringified data into the URL.
- Local context navigation event handlers are triggered, becon.html's new URL is parsed, and the hashtag section is processed.
- Real API calls are made accordingly in the local context.
- Results are sent back directly to the remote bridge through invokeScriptAsync().
- The bridge calls the previously stored callbacks, with the results from the local context.
A bridge has two parts: one inside the local context in script tags (bridge client), and the other injected into the remote context (bridge server). The means you must create API bridges for each plugin that is supported in the Custom SAP Fiori Client. To add a new plugin for a Custom SAP Fiori Client, customers must write their own bridges for Windows only.
Windows 10 Alternatives
On Windows 10, you can provide a list of WinRT-allowed URLs before building the application. It now seems possible to inject cordova.js into the webview to allow Fiori Apps to access Cordova plugins directly, making bridges obsolete for custom Fiori Clients. (The SAP Fiori Client will continue to use bridges even on Windows 10.)
However, Cordova injection is still not feasible. Injecting Cordova into a remote page initializes the JavaScript APIs (which is expected), but also creates new instances for the plugins' platform-specific parts. In contrast, on Android, the native side of the plugins is initialized only once, so the JavaScript APIs can reload independently and continue to access persistent plugin data.
Cordova JavaScript APIs and the "native" proxy APIs load simultaneously together. Injecting Cordova into a web page creates new instances of the entire plugin architecture for the webpage's context, independent of the plugins that are already instantiated in index.html. No persistent "native" data can be accessed by the injected plugins.
Each navigation and each Cordova injection results in a completely new set of plugins that do not share the same data.
