Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
BWomelsdorf
Advisor
Advisor
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:


    1. Create a folder with the name of your plugin. In this case “CustomLogon”.

    2. Underneath this folder, create a folder called “scripts”

    3. 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:

  1. Add the plugin the mobile service for SAP Fiori plugin repository as a Custom Plugin

  2. Add the plugin to your app and specify the setting you want to enforce.

  3. 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.

 
4 Comments