Skip to Content
Product Information

What’s new in Mobile development kit client 5.0

I am happy to announce that a new release of the Mobile Development Kit is now available for all Mobile Services customers and can be downloaded on the SAP Software Center and community Download page).

SAP Mobile Services Client 5.0 is also available in Google Play Store and in Apple app store.

SAP Mobile Development Kit (MDK) extends SAP Cloud Platform Mobile Services and Editor (SAP Web IDE/SAP Business Application Studio/Visual Studio Code extension) to provide you with a complete set of mobile application development and management tools including on-boarding, offline support, and central lifecycle management. It offers a metadata-driven approach to create native supported applications, so no experience with creating iOS or Android apps is required. Additionally, MDK now extends that capability to the Web as well.

The release includes the following:

MDK Web Client

We introduce MDK Web Client, which extends the MDK capabilities to the desktop, complementing existing MDK Mobile Clients (Android & iOS). You can now build and maintain a single app that runs natively on Mobile (Android & iOS) and as a web application (online) in the browser.  The MDK Web Client is available in trial and as well as productive accounts. MDK Web Client is an important delivery of the SAP Cloud Platform Extension Suite and offers new Low-Code features which helps business developers to contribute in building extensions.

You can find more details in the announcement post.

Master Detail –  Flexible Cloumn Layout

There is a new page type “Master Detail Page” supporting two columns, so you can have a split screen where you can have a list and details on the same screen. This is available in both MDK Mobile & Web clients.

Note: Master-detail two sections floor plan are only for Tablet with both of landscape and portrait. It will automatically default to Master-only on mobile phones in both landscape and portrait modes.

Check the documentation for more details.

Side Drawer Navigation

There is a new page type “Side Drawer Navigation Page” which provides a slide out menu navigation option.

This page type can be used to provide the similar functionality to the bottom navigation page type but supports more than 5 areas within your application. This page type can only be used as the MainPage in the Application.app file.

Check the documentation for more details.

Support Header Type control & Tabs in a page

We have enhanced tabs pages to support displaying the header above the tabs so you can have a persistent header (Object, KPI, Profile).

Check the documentation for more details.

Searching across multiple sections in the same page

We have enhanced the search to support searching across multiple sections of the page. Previously, search was only available when you had a single section. You can now set multiple sections within the page to support search and each section will apply the search criteria and update the Target query options based on the input.

Password Input Type in Simple Property control

We introduced two additional Keyboard Types: Password & NumberPassword for the Simple Property Form Cell control.  Values input in Simple Property fields with these keyboard types will automatically mask the input values.

Note: NumberPassword will show only numeric keyboard.

Check the documentation for more details.

SetFocus API for Title, SimpleProperty and Note Form Cell controls

We are introducing a new SetFocus API to allow the developers to programmatically set focus to the following Form Cell field type (Title, Simple Property, Note).

Some possible use cases include:

  • Moving the input to a certain field based on the input in the current field.
  • If the field is a specific length, the app could set focus to the next field once the value has been validated or reached the specific length of the field.
  • If an error occurs on the screen, taking the user to the specific field which is in error

Check the documentation for more details.

New Page level PullDown event

We have added a new page level event so you can define an action to execute on pull down of a page. It’s up to developer what they want to do. One use case is to for an online application to refresh the list when the user pulls down on the page.

PullDown event will be executed when user swipes down from the top of the page.

//Excerpt of a page

"PullDown": {
    "OnPulledDown": "/MDK50/Actions/Service/Initialize_SampleSrvc_online.action",
    "Styles": {
        "BackgroundColor": "#b23965",
        "IndicatorColor": "#b4bfc6"
    }
},

Check the documentation for more details.

Activity indicator when loading the page

You can now display an activity indicator when page is being loaded and will be dismissed when its content is rendered.

//Excerpt of a page

"LoadingIndicator": {
    "Enabled": true,
    "Text": "Data loading please wait..."
},

Check the documentation for more details.

Busy indicator at lazy loading time

You can now display a busy indicator when the lazy loading happens. This indicator is shown below the list while the new set of data is being downloaded.

You need to set DataPaging properties of the controls.

//Excerpt of a page

"DataPaging": {
    "LoadingIndicatorText": "Loading more items, please wait...",
    "ShowLoadingIndicator": true
},

Check the documentation for more details.

New Unified OData Service Initialize Action

We have now unified the Offline OData Initialize, OData Service Create and OData Service Open actions into a single action: OData Service Initialize.

This new action can be used to initialize either offline or online OData services. You can now easily switch between offline or online by just changing the OfflineEnabled flag in .service file.

With the introduction of this new action, the following actions are now deprecated:

  • Offline ODataInitialize (Type.OfflineOData.Initialize)
  • OData ServiceCreate (Type.ODataService.Create)
  • OData ServiceOpen (Type.ODataService.Open)
//Excerpt of a page

{
    "ActionResult": {
        "_Name": "init"
    },
    "DefiningRequests": [{
        "Name": "Categories",
        "Query": "Categories"
    }],
    "OnFailure": "/MDK50/Actions/Service/InitializeOfflineFailureMessage.action",
    "OnSuccess": "/MDK50/Actions/Service/Initialize_SAM2005Online.action",
    "Service": "/MDK50/Services/ODataDemo.service",
    "_Type": "Action.Type.ODataService.Initialize"
}

Check the documentation for more details.

Support Partial Uploads for Offline OData

From an offline perspective, you can now define categories for your transactions and upload only certain transactions.

Possible use cases:

  • you can just send Status updates,
  • If a user is on a cellular network he may want to just sync partial changes to the backend
  • If a uses adds an attachment to one of the work orders and subsequently makes a status update to another workorder then the user may want to just update the workorder status for one and upload the attachment for other only when user is in a Wi-Fi network.

In an OData actions, you need to set UploadCategory in RequestOptions property of the action.

//Excerpt of a page

{
    "OnFailure": "/MDK50/Actions/PartialUpload/CreateCustomerEntityFailureMessage.action",
    "OnSuccess": "/MDK50/Actions/CloseModalPage_Complete.action",
    "Properties": {
        "FirstName": "#Control:FCCreateFirstName/#Value",
        "LastName": "#Control:FCCreateLastName/#Value"
    },
    "Target": {
        "EntitySet": "Customers",
        "Service": "/MDK50/Services/Sample.service"
    },
    "RequestOptions": {
        "UploadCategory": "Customer"
    },
    "_Type": "Action.Type.ODataService.CreateEntity"
}

Check the documentation for more details.

And in the OfflineOData Upload action, you need to provide UploadCategories property to selectively upload data.

//Excerpt of a page

{
    "Service": "/MDK50/Services/sample.service",
    "UploadCategories": [
        "Customer"
    ],
    "_Type": "Action.Type.OfflineOData.Upload",
    "ActionResult": {
        "_Name": "upload"
    },
    "OnSuccess": "/MDK50/Actions/PartialUpload/DownloadStartedMessage.action",
    "OnFailure": "/MDK50/Actions/PartialUpload/UploadFailureMessage.action"
}

Check the documentation for more details.

Added OData Deep Insert support

A deep insert is an OData POST request to create an entity that also contains inline related entities. When a deep insert is processed, the top-level entity and all its related entities are created and related together as a single operation.

MDK now supports Deep Insert in CreateEntity action. Please keep in mind that while using deep insert, you as a developer needs to take care for managing temporary data especially in case of 1:many. You need to track and manage UI to be able to input an array of items and make one call (POST) to the backend.

Note: Offline OData only supports 1-to-1 deep link relationships while online can support both 1-to-1 and 1-to-Many relationships.

Check the documentation for more details.

REST Service support with Target binding

  • We have added support for REST Service endpoints (e.g., REST API from SAP Business Hub, Public API with no authentication) by providing an additional option in the Service definition.
  • Consuming REST services is similar to how we support online OData services.
  • You need to first define REST endpoint as a destination in Mobile Services (for Mobile app) or in Cloud Foundry (for web app) and then while creating a service file, select “REST Service” option.

You can then easily bind a RestServiceTarget to an MDK control e.g., ObjectTable, ContactCell, ObjectCollection etc. and select GET method in RequestProperties. This assumes the REST service returns JSON similar to how OData requests are returned.

  • We have also introduced a new Action “RestService SendRequest Action” (equivalent of the sendRequest API) to make directly call against REST endpoint.

Example for RESTService SendRequest Action (POST method):

//MyApp/Actions/CreatePet.action
{
    "_Type": "Action.Type.RestService.SendRequest",
    "Target": {
        "Path": "/pet",
        "RequestProperties": {
            "Method": "POST",
            "Body": {
                "name": "{#Control:FCCreateCategory/#Value}"
            }
        },
        "Service": "/MDK50/Services/Pet_store.service"
    },
    "ActionResult": {
        "_Name": "create"
    },
    "OnFailure": "/MDK50/Actions/CreateEntityFailureMessage.action",
    "OnSuccess": "/MDK50/Actions/CloseModalPage_Complete.action"
}
  • We have also enhanced the sendRequest API to support setting the request body directly with:
    • JSON object which will automatically be converted to JSON string with header Content-Type: application/json, if you have not provided your own Content-Type header.
    • Binary data, you need to set the appropriate Content-Type.
    • Array for multiple part form data by setting the header Content-Type: multipart/form-data

Check the documentation for more details.

Support complex Filter and Sort criteria returns

We have enhanced the Filter returns so that you can create complex expressions in the filter to make it easier for developers to define Filter criteria on lists.

  • Rules support for filter and sorter form cell
  • Support of standard OData logical operators such as less than, greater than, not equals and others
  • Support of standard OData functions such as startswith, endswithand others
  • Support of standard ascending and descending operators for sorter form cell
  • Support for Lambda operators (any & all) for OData V4 and offline V2

Expose OData Error response body in Action result

We have enhanced the results coming back from OData servers to expose the full error response body in the action result.  In case of errors the application can parse the response and display the server returned error message. This applies to online OData service calls.

ActionResult.error now contains the following new properties

  • responseCode – this is the HTTP error code in the response returned by the OData service (e.g., #ActionResults:update/responseCode)
  • responseBody – this is the response body pay load returned by the OData service in string format. If the payload is a JSON string, you can parse it to be an JSON object for further processing. (e.g., #ActionResults:update/responseBody)

Check the documentation for more details.

Action support in Banner Message & Progress Banner

Banner Message & Progress Banner now support interactivity which can be used to execute an action or rule on click.

Expanded Font Icon Styling

We have now introduced support for styling on font-icon e.g. sap-icon://add.

//Excerpt of a page

"Styles": {
    "DetailImage": "font-icon-class",
    "StatusImage": "font-icon-class",
    "SubstatusImage": "font-icon-class"
}
////Excerpt of a Less file

.font-icon-class {
    font-size: 8;
    color: red;
}

Enhanced List Picker to support defaulting the selection if only one value exists

You can now default the list picker if there is only one value. This helps the user by not  having to click into the list to make a selection when there is only one choice.

//Excerpt of a page

{
    "AllowDefaultValueIfOneItem": true,
    "AllowEmptySelection": false,
    "AllowMultipleSelection": false,
    "Caption": "Product",
    "IsEditable": true,
    "IsVisible": true,
    "PickerItems": {
        "DisplayValue": "{Name}",
        "ReturnValue": "{ProductId}",
        "Target": {
            "EntitySet": "Products",
            "Service": "/MDK50/Services/sample.service"
        }
    },
    "PickerPrompt": "Please select one single item",
    "_Name": "FormCellListPicker0",
    "_Type": "Control.Type.FormCell.ListPicker"
},

Check the documentation for more details.

New Default Value Metadata function

We now provide you a Default Value metadata function to return a default value if a binding is evaluated to undefined, null or empty string. This will save having to write a rule every time to check if a value exists and return either the value or default.

Format:

$(DV,<binding value, rule, target path>,<default value,rule,global>)

 e.g. $(DV,{Name},’Unknown’)

  • If {Name} contains “ABC”, then it should resolve to “ABC”
  • If {Name} contains “” or null or undefined, then it should resolve to “Unknown”

Some additional examples:

$(DV,{Name},{AnotherBindingOrTargetPath})
$(DV,{Name},'/MyApp/Globals/SomeGlobalProp.global')
$(DV,{Name},'/MyApp/Rules/SomeRules.js')
$(DV,{Name},$(L,'some_localized_string_key'))

Check the documentation for more details.

Avatar and Circular Icon Support for Action Bar Item

We introduce 2 additional properties in Action Bar:

  • IconText : is used to generate a text based avatar image
  • IsIconCircular: can be used to render a circular icon.
//Excerpt of a page
{
    "IsIconCircular": true,
    "Position": "right",
    "Visible": true,
    "IconText": "MDK Developer"
}​

Check the documentation for more details.

Support scanning InApp QR Code for onboarding from Mobile Services cockpit in Cloud Foundry

MDK Mobile client now supports the In-App QR code available in Mobile services cockpit of Cloud Foundry.

ILODATA tool included in the MDK SDK

Mobile Development Kit Client package now includes the ILOData tool in the SDK Tools/ilodata folder.

The Interactive Local OData (ILOData) tool is a command line utility that lets you execute OData requests, upload and download against a local offline store (.udb file). For details please see the README.html in the folder.

 

New to MDK development?

Follow these tutorials to get your hands dirty and learn more about Mobile development kit!

Further Information:

You can learn more in documentation :

I am looking forward to your feedback and comments.

Jitendra

8 Comments
You must be Logged on to comment or reply to a post.
  • Hi Jitendra,

    Thanks for this blog.  Some really nice new features.  A couple of questions.

    1.  When will these new features be available for the cloud build service?  I tried to do a rebuild on one app and it is still using the 4.X framework versions and the new features like the persistent object header on the tabbed page don’t yet work.
    2. I have one app which I am using a tabbed page with an object header.  From that page an update can be called to approve / reject in the OData service.  The object header includes a status field that is updated when the update takes place.  I notice that the object header on the tabbed page doesn’t update / redraw with the new status value after the update action occurs.  All of the pages within the tab page update with the new binding values, but not the object header.  Is this a bug?  Or is there something additional that needs to be done to make that occur?

    Thanks,

    Jeff