One of the values propositions, indeed one of the "missions" of the mobile service for SAP Fiori is that it allows enterprises to create a customized, enterprise branded SAP Fiori client without requiring any on-premise development infrastructure. One of the challenges of any process that replaces direct code access with wizards and workflows is that in some scenarios you have to wait until the option is visible in the workflow before the workflow can set the underlying project setting.
Or do you?
Let's be honest, in some scenarios, you do. But not for everything. The SAP Fiori Client team stores most, if not all of the configuration settings in the appconfig.js file. Some of those settings, like password policy, are already exposed through the mobile service for SAP Fiori UX. When the app runs, the Kapsel SDK reads the appconfig.js settings and directs the client to behave in a certain way.
What you may not know is that other settings can be configured even without direct access to the file. The way we do this, and the subject of this blog, is through a custom Cordova plugin.
Our Scenario
In this case, as you can see, the purpose of this plugin is to enable the removal of the Fiori app passcode screen. You know, the screen that looks like this:
Why would you want to remove this screen? Well, your reasoning might vary, but some customers feel that the user authentication is sufficient, and that an additional authentication screen might be too burdensome on their end users. The point is, you want to remove it, and in our scenario, and (in the Fiori Mobile scenario) you don't have access to the SDK to update the project files directly.
What is a Cordova plugin?
A complete overview of Cordova is beyond the scope of this blog. Cordova is a framework for hybrid web development and is built on the concept of plugins. A plugin is a package of injected code allowing access to device platform functionality that is ordinarily unavailable to web-based applications. The Kapsel SDK is, in fact, a series of Cordova plugins. The SAP Fiori Client is a Cordova app. In the mobile service for SAP Fiori, developers can add plugins to their app either through the admin console or through SAP Web IDE. This lets the resulting app do different things that the developer needs or wants it to do, either to solve a business or in this case technical challenge. For more information on Cordova plugins, I recommend you go directly to the
Plugin Development Guide on the Cordova site.
The Kapsel Logon Plugin
The plugin that we are going to work with in indirectly in this blog is the
Kapsel Logon plugin, part of the Kapsel SDK. The Logon plugin manages the application registration and authentication process either through the mobile service for SAP Fiori, mobile service for development and operations, an on premise SAP Mobile Platform Server or through SAP Gateway server.
The Logon plugin takes its direction from the appconfig.js file. Not all of the settings are exposed currently through the mobile service for SAP Fiori UX, but they can be set - through the creation of a custom plugin. By creating the plugin correctly, these previously inaccessible settings can then be set by a developer or admin when the app is built. The plugin code will then update the appconfig.js setting, and the Logon manager can change the appropriate behavior at runtime. It's important to note that these are build time settings, not runtime settings. Changing the setting requires the app to be rebuilt and redistributed to the mobile device. Please refer to the
following documentation for a description of the types of things that can be customized.
NOTE: What follows are steps you want to follow if you are using the mobile service for SAP Fiori. For customers who have purchased the mobile service for development and operations or SAP Mobile Platform, who have invested in on-premise development landscape, there is an excellent blog by Daniel Van Leeuwen on how to customize the SAP Fiori Client experience. You can find it
here.
Create a plugin skeleton
Before generating the skeleton for your plugin, you should decide on the plugin's ID and name. In particular, the ID should be unique, and should follow the convention "cordova-plugin-[your-plugin-name]".
For our tutorial let’s assume the plugin id is
kapsel-plugin-custom-logon-plugin and the name of the plugin is
CustomLogon.
Now that we've decided on what our plugin will do and what it will be called, we're ready to create the skeleton. Since this plugin is rather simple, we will do this by hand by following these simple steps:
Steps:
- Create a folder with the name of your plugin. In this case “CustomLogon”.
- Underneath this folder, create a folder called “scripts”
- Using your favorite text editor, create under the root of CustomLogon a file called plugin.xml with the following contents (Notice that we are using the plugin id we specified earlier):
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android"
id="kapsel-plugin-custom-logon-plugin"
version="1.0.5">
<name>FioriClient AppConfig Modifier Plugin</name>
<hook type="after_plugin_add" src="scripts/modifyAppConfig.js" />
<preference name="disablePasscode" default="false" validationExpression="true|false"/>
</plugin>
There are a couple entries in this file that have special significance. First, let's look at the <preference/> entity:
<preference name="disablePasscode" default="false" validationExpression="true|false"/>
When this plugin is loaded into the mobile service for SAP Fiori admin UX, this element will be used to allow the administrator to specify a value (true/false, as specified in the
validationExpression attribute) for a variable named
disablePasscode. If the admin does not specify a value, the default value of
false will be assumed. When the mobile app is ultimately built, this name/value pair will be passed in to the build process as a command line argument. If we had multiple
<preference/> attributes you will see multiple entries in the UX, and the
validationExpression allows the mobile service to validate the input.
The next thing we want to look at is the
<hook/> element:
<hook type="after_plugin_add" src="scripts/modifyAppConfig.js" />
Hooks allow you to perform special activities around Cordova commands. For example, you may have a script that checks for code formatting in your javascript file. You’d like to run this script before every build is executed. In such a case, you could use a 'before_build' hook and instruct the Cordova run time to run script before every build. In our case we are calling the
after_plugin_add hook, which will execute the script
scripts/modifyAppConfig.js after the plugin is added. For more reference on hooks please check the link
cordova hooks.
In the next step, we will our script.
4. Under the scripts folder, using your favorite text editor, create a file called modifyAppConfig.js.
Once the
plugin.xml file with the appropriate hook is created, we need to define the script that is going to do the actual work. The scenario for our script is relatively simple. Read all the preference value passed into the build, and write the variable and its value to the
appconfig.js file. In our scenario, we have only one entry, for
disablePasscode, as described earlier:
<preference name="disablePasscode" default="false" validationExpression="true|false"/>
When the app launches, the Kapsel Logon plugin will read the
appconfig.js file and alter the behavior of our app.
To create the contents for this file, use the following as a guide:
First, let's create the structure for the overall script:
#!/usr/bin/env node module.exports = function(context) {
// All your content will go in here
};
Sometimes plugins are called multiple times during a build process. To make sure it is called only once, add a check so that it is only checked by your plugin:
if(context.opts.plugins != undefined && context.opts.plugins.indexOf("kapsel-plugin-custom-logon-plugin") == -1) return;
Since there will be file operations, include the required modules:
var fs = context.requireCordovaModule('fs'),
path = context.requireCordovaModule('path'),
shell = context.requireCordovaModule('shelljs');
Next, we reference the www folder of the Cordova project:
var projectWWWDir = path.join(context.opts.projectRoot, 'www')
To be able to make dynamic changes and have access to existing values, you can load the appconfig.js file into the runtime. To do so, you need to make sure that the necessary object (fiori_client_config) is exported:
shell.sed('-i', /fiori_client_appConfig/, 'exports.fiori_client_appConfig', path.join(projectWWWDir, 'appConfig.js'));
Now you can load the fiori_client_appConfig as an object into the Cordova's NodeJS runtime:
var appConfigJS = require(path.join(projectWWWDir, 'appConfig.js'));
var fiori_client_appConfig = appConfigJS.fiori_client_appConfig;
Now you can take the preference values that the user entered and update/write it to the appconfig object. Remember that in our scenario, we have included a single preference, "disablePasscode" (reference the plugin.xml):
if(context.opts.plugin && context.opts.plugin.pluginInfo && context.opts.plugin.pluginInfo._et
&& context.opts.plugin.pluginInfo._et._root && context.opts.plugin.pluginInfo._et._root._children
&& context.opts.cli_variables)
{
for(i in context.opts.plugin.pluginInfo._et._root._children){
//find the desired preference with name and value from the current runtime context
var p = context.opts.plugin.pluginInfo._et._root._children[i];
if(p.tag == "preference" && p.attrib && p.attrib.name){
var preferenceVariableName = p.attrib.name;
var preferenceVariableValue = context.opts.cli_variables[preferenceVariableName.toUpperCase()];
//write the correspondig key value pair into the fiori_client_appConfig
//if your value is meant to be a boolean, make sure booleans are written as booleans and not strings
fiori_client_appConfig[preferenceVariableName] = preferenceVariableValue == "true" || preferenceVariableValue == "false" ||preferenceVariableValue;
}
}
}
And remember to write the changed object back into the correct file:
fs.writeFileSync(path.join(projectWWWDir, 'appConfig.js'),'fiori_client_appConfig = ' + JSON.stringify(fiori_client_appConfig, null, '\t'));
When you are finished, zip the entire folder. You should have a file called “CustomLogon.zip” when you are done.
Using the Plugin
Let's review. We've created ourselves a nifty Cordova plugin using nothing but a text editor. The next step is to use it! To use this plugin we have to perform three simple steps:
- Add the plugin the mobile service for SAP Fiori plugin repository as a Custom Plugin
- Add the plugin to your app and specify the setting you want to enforce.
- Build your app and deploy it to your mobile.
Adding the Custom Plugin
To add the custom plugin in Fiori Mobile you will need to have the App Catalog Admin Role assigned. This is done through
HCP > Services- > Fiori Mobile > Configure Fiori Mobile > Roles and make sure that your user is part of this role:
As an App Catalog Admin go to your Fiori Mobile account and select
Applications > Manage Plugins. Select the
+ Custom Plugin button
Select the
Browse… button and find the CustomLogon.zip file and then press
OK. You will be prompted with information about the plugin, and can specify the default behavior for the newly added plugin:
Notice that you see the
disablePasscode variable and that it's default value is false as specified in the
plugin.xml. Once it’s been added you can now begin creating your Fiori Mobile Client.
Using the plugin in your Fiori mobile app
This blog assumes that you have basic working knowledge for how to use the mobile service for SAP Fiori. There are a couple existing blogs that cover getting started, for example How to use
SAP HCP, mobile service for SAP Fiori and
The Fiori mobile service developer experience has arrived! Our new plugin can be added either in support of the developer persona (through the mobile service for SAP Fiori developer experience tools), or by the admin/devops persona. We'll use the admin/devops persona in the example, so we'll assume that you have your environment already setup and that you know how to create a Fiori mobile app. If you don't, I suggest you review these blogs and perhaps some of the other blogs referencing the mobile service for SAP Fiori.
Create a new SAP Fiori mobile app by clicking on Applications > Manage Apps. Finish the workflow, but instead of building your app, select the "No, I would like to customize my application":
When the app opens, select
Plugins from the tool bar, and then click the
Custom tab. From the
Actions icon select
Add. This tutorial shows you how to use the custom plugin we just wrote, but Fiori Mobile also allows the use of over 1500 Public Plugins. If the Plugin you would like to use is Public you can select the Public option and Search for it to see if it’s available.
You will receive a prompt that the plugin was added, you can change the default preference variable values. Once the plugin is added click the
Save button to save your changes.
At this point the app has been defined and the plugin has been added. The only thing left to do is build and test it out! To build the app, click on the
Platforms tab, then click the
Build All button and build your app. When the build is complete you should receive an email with a link to download and use the app. If you changed the value for disablePasscode from false to true, you should no longer see the app passcode screen. See how easy that was??
Special thanks to Jan Schober and Akarsh Siddhartha for their significant input into creating this blog.