This is part three of a four-part blog series about building hybrid mobile apps with Mendix. Part one is about preparing your software, devices, and accounts, while part two is about building an actual app. Read part one here, part two here. In this part I’ll go into the more technical topics of developing mobile apps.
Hybrid Mobile App
As explained in part two of this blog series, we use PhoneGap as a basis for Mendix hybrid mobile apps, which is based on the Cordova framework. The picture below shows a simplified overview of the different components in a Mendix mobile application and how they interact.
It is important to understand that when something changes in the Mendix hybrid app code or in the configuration, the app needs to be rebuilt, whereas a change in the model only requires a restart of the app. The idea of the Mendix approach is that you configure and generate your app once, because the logic and the user interaction is defined the model. As most changes are done in the Mendix Modeler, updating your app is very fast and easy.
The Structure of a Hybrid App
You can download the hybrid app for your project via the publish tab in the Mendix Developer Portal. When you unpack the downloaded archive you get the following file structure:
|config.xml||The Cordova configuration that contains:
|index.html||The page that is initially loaded by Cordova. This page contains, among other things, the URL of your Mendix server, and the container in which your Mendix app is loaded.|
|res||Platform-specific images for splash screens and icons.|
|css||The CSS needed for the Hybrid app, for example, the loading screen, the login screen, and the error dialog.|
|img||Images used by the Hybrid App.|
For more information about config.xml, see the Cordova documentation.
The config.xml contains a widget element where you define the ID and version number of the app. The ID is what makes the app uniquely identifiable. Once you’ve uploaded your app to one of the stores you cannot change this ID anymore. When you send a new release to Apple or Google, the version should be increased, because there can always be only one active version.
If you want to test your app with your local model on your machine, you should change the URL in the mxapp.Initialize method in the index.html to the IP address of your machine, like this:
mxapp.initialize("http://192.168.1.15:8080/", enableOffline, requirePin);
Make sure that your machine and mobile device are on the same network and that your firewall is not blocking the incoming port.
Tip: If you want to have multiple versions of your hybrid app on your device, you can use different IDs, like com.mendix.mendixworld2016.accp and com.mendix.mendixworld2016.test. It can also be useful to change the name so you can easily tell them apart.
The default configuration ships with several plugins so that many widgets will work out of the box. However, this causes the app to ask for more permissions than are actually needed, which might be undesirable, like asking permission for the phone’s location. Also, plugins can have a negative impact on performance.
The following list shows the most important plugins at the moment of writing. It is advised to keep these plugins enabled. You can enable or disable other plugins based on the widgets and functionality you use.
- cordova-plugin-secure-storage * (needed for PIN)
- Required for the app to work correctly.
** Not enabled by default. This plugin requires additional configuration, see the next section.
For more plugins and information about the plugins, see https://cordova.apache.org/plugins/.
WKWebView plugin for IOS
As mentioned above, the WKWebView plugin is not enabled by default because of backwards compatibility. I strongly recommend enabling this plugin because its performance is better than the previous WebView UIWebView and it solved some bugs. When you add this plugin you should also add the following configuration:
<feature name="CDVWKWebViewEngine"> <param name="ios-package" value="CDVWKWebViewEngine" /> </feature> <preference name="CordovaWebViewEngine" value="CDVWKWebViewEngine" />
Crosswalk Plugin for Android
The Crosswalk plugin is included in the package and packages the latest WebView with the hybrid app so that all the apps run in the same WebView, regardless of the device. This makes your app more consistent across devices and therefore less prone to errors.
Crosswalk needs to know the target architecture/CPU of the devices to package the right version of the WebView. There are generally two types of CPUs: ARM and x86. By default, your mobile app will be built for ARM, which is used for 98.7% of the Android devices (according to http://hwstats.unity3d.com/mobile/cpu.html). You can build for x86 by adding the following lines to config.xml:
<preference name="buildArchitecture" value="x86" />
You can place this under the line:
<plugin name="cordova-build-architecture" spec="https://github.com/MBuchalik/cordova-build-architecture.git#v1.0.1" source="git" />
If the above plugin is not defined (in an older hybrid app version), you should add this. It is also possible to specify ARM (with armv7) as an architecture. The Google Play Store allows you to upload multiple APKs so that you can support both types of CPUs.
Changing the Loading Screen
When the app is loaded, a native splash screen is shown first, followed by a loading screen (the screen with the moving circles), while the Mendix client is being loaded. This loading screen is placed in the div element with the mx-app ID. When the Mendix client is successfully loaded, this div element is removed and the Mendix page is loaded in the content div element. The mx-app div element also contains an alert in case something goes wrong while loading the app.
For the Mendix world app we wanted to change the loading screen, so the hybrid app needed to be changed. This was done by removing the loader image and replacing the CSS in /css/index.css with our new CSS.
When making changes to the hybrid app, it is important to put the source under version control so that changes are tracked and collaboration is possible. A simple approach is to add the source files to your Mendix project. You can do this by adding the HybridApp folder to your Mendix project folder so that the files are in the same SVN repository. When you commit you model, your hybrid app source code is also committed.
You can also use an SVN client like TortoiseSVN to make commits. Mendix requires the 1.7 version of SVN, which you can download here: https://sourceforge.net/projects/tortoisesvn/files/1.7.15/.
Warning: When you commit from the Modeler, the changes in your HybridApp folder are also committed.
Tip: Only commit changes to the hybrid app from the HybridApp folder via TurtoiseSVN, so that only these files are committed, and not your model.
Interacting With Device Functionality
It is important to understand that you cannot interact with native device functionality from within a microflow, only via widgets. Widgets can interact with the device via Cordova plugins. There are many plugins available for Cordova/PhoneGap at http://cordova.apache.org/plugins/.
We created a native share widget for the Mendix World app that allows users to share content via Twitter, Facebook, and WhatsApp via the native share functionality of the device with the help of the cordova-plugin-x-socialsharing plugin. You can add a plugin by adding its name, source, and version to the config.xml like this:
<gap:plugin name="cordova-plugin-x-socialsharing" source="npm" version="5.1.3"/>
The version is optional but I recommend always adding it because it allows you to control when you update the version and you will not be surprised if the plugin/app behaves differently after a build. After you add the plugin definition you need to rebuild your app. The APIs of the plugins are usually added to the window.plugins object. For example, the social sharing plugin has a share method:
window.plugins.socialsharing.share(msg, subject, null, link);
Tip: Check whether the plugin can be accessed and make sure you have a fallback when the widget is used in the browser, so that users don’t get unexpected errors. For example:
var pluginAvailable = window.plugins && window.plugins[“socialsharing”];
When you start building your mobile widget I recommend taking a look at the source code of a couple of PhoneGap widgets, like: Share Widget for PhoneGap, Camera Widget for PhoneGap and Add to Calendar Widget For PhoneGap.
This blog covered the more technical topics of mobile apps with Mendix, which is a good starting point to create fancy mobile widgets or adjust the hybrid app to your wishes. Next week I will discuss how you can build your mobile app locally instead of via Phonegap Build, along with an explanation about how you can debug your mobile app. Have fun with creating awesome mobile features!