Hybrid Mobile Application

This section explains how to build one hybrid application based on a Simplicité project:

Cordova

Prerequisites

Environment variables

Install cordova CLI

npm install -g cordova`
cordova --version

Create your application

cordova create myproject com.simplicite.mobile.myproject MyProjectName
cd myproject

Add platforms and plugins

cordova platform add android
cordova plugin add cordova-plugin-whitelist
cordova plugin add cordova-plugin-inappbrowser
cordova plugin add cordova-plugin-network-information
cordova plugin add cordova-plugin-dialogs

Androïd test

Create/launch one emulator in Android Studio then:

cordova build android
cordova emulate android

Starts on your device in debug mode

cordova run android

Integrate the hybrid app

Open your project directory and customize your application:

Script www/js/index.js

(function() {

    var url = 'https://myproject.dev.simplicite.io';
    var fireBaseToken, win, winReady;

    // Call the UI firebase handler
    function exec(d) {
        d = typeof(d)=="string" ? d : JSON.stringify(d);
        winReady && win.executeScript({ code: 'window.$ui.firebase(' + d + ');' });
    }

    // Notify server with firebase token after login
    function syncFirebaseToken(token) {
        token = token || fireBaseToken;
        if (token) {
            fireBaseToken = token;
            exec({ token:token });
        }
    }

    function error(e) { console.error(e); }

    // Firebase events
    function firebase() {
        // Notification : cordova-plugin-firebase
        var pfb = window.FirebasePlugin;
        if (pfb) {
            console.log("[FirebasePlugin] init");
            //pfb.grantPermission();
            pfb.getToken(syncFirebaseToken, error);
            pfb.onTokenRefresh(syncFirebaseToken, error);
            pfb.onNotificationOpen(function(m) {
                console.log("[FirebasePlugin] onNotificationOpen " + JSON.stringify(m));
                exec(m);
            }, error);
        }
    }

    // Load Simplicite URL
    function open() {
        // In-app browser
        win = cordova.InAppBrowser.open(url + "?inapp=true", '_blank', 'location=no');
        win.addEventListener('loadstop', function() {
            winReady = true;
            syncFirebaseToken();
        });
        //win.addEventListener('exit', function() {});
    }

    // Cordova loaded
    function init() {
        var parentElement = document.getElementById('deviceready');
        var listeningElement = parentElement.querySelector('.listening');
        var receivedElement = parentElement.querySelector('.received');
        listeningElement.setAttribute('style', 'display:none;');
        receivedElement.setAttribute('style', 'display:block;');
    }
    function ready() {
        init();
        firebase();
        open();        
    }
    document.addEventListener("deviceready", ready, false);
})();

Application icons

    <platform name="android">
            ...
        <icon density="ldpi" src="res/icon/android/icon-36-ldpi.png" />
        <icon density="mdpi" src="res/icon/android/icon-48-mdpi.png" />
        <icon density="hdpi" src="res/icon/android/icon-72-hdpi.png" />
        <icon density="xhdpi" src="res/icon/android/icon-96-xhdpi.png" />
    </platform>
    <platform name="ios">
            ...
        <icon height="114" src="res/icon/ios/icon-57-2x.png" width="114" />
        <icon height="57" src="res/icon/ios/icon-57.png" width="57" />
        <icon height="144" src="res/icon/ios/icon-72-2x.png" width="144" />
        <icon height="72" src="res/icon/ios/icon-72.png" width="72" />
    </platform>

Firebase configuration

Firebase is used to manage Cloud messaging and notifications.

The platform will use several system parameters:

Register your application on Firebase

  1. Create your Firebase account https://firebase.google.com
  2. Access to the console to add your project, ex SimpliciteMobileMyProject

Add to project the application for Androïd

Add the firebase plugin

Notification https://github.com/arnesson/cordova-plugin-firebase

cordova plugin add cordova-plugin-firebase
cordova run android

Send a message with the console

https://console.firebase.google.com/u/0/project/simplicitemobilemyproject/notification/compose

Back-end integration

Set system parameter FIREBASE = yes to activate the service. On UI $ui.firebase wrap all Firebase message:

on Server-side service, see GoogleFireBaseTools

https://console.firebase.google.com/u/0/project/simplicitemobilemyproject/settings/serviceaccounts/adminsdk

{
  "type": "service_account",
  "project_id": "simplicitemobilemyproject",
  "private_key_id": "41d94061ba24e55a0b74b5xxxxxxxxxxxxxx",
  "private_key": "-----BEGIN PRIVATE KEY-----\nxxxxxxxxxxx\n-----END PRIVATE KEY-----\n",
  "client_email": "firebase-adminsdk-xxxxxx@simplicitemobilemyproject.iam.gserviceaccount.com",
  "client_id": "10898538xxxxxxxxxxxxx",
  "auth_uri": "https://accounts.google.com/o/oauth2/auth",
  "token_uri": "https://oauth2.googleapis.com/token",
  "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
  "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/firebase-adminsdk-xxxxxx%40simplicitemobilemyproject.iam.gserviceaccount.com"
}

Front-end integration (desktop)

To receive message on webapp, the browser needs 2 parameters:

  1. Add a public system param FIREBASE_LIBS
["https://www.gstatic.com/firebasejs/5.5.3/firebase-app.js"
,"https://www.gstatic.com/firebasejs/5.5.3/firebase-messaging.js"]
  1. Add a public system param FIREBASE_CONFIG to init firebase on client-side:
{
"apiKey": "AIzaSyB...",
"authDomain": "simplicitemobilemyproject.firebaseapp.com",
"databaseURL": "https://simplicitemobilemyproject.firebaseio.com",
"projectId": "simplicitemobilemyproject",
"storageBucket": "simplicitemobilemyproject.appspot.com",
"messagingSenderId": "134..."
}
  1. Add a public system param FIREBASE_VAPID_KEY to authent client

Get the public VAPID key from key-pair on Firebase console / Configuration web:

BIDDmZgk5QSFd7Bf1sf2yfUrfi...

note firebase is not loaded in webapp:

Unit test

JSON message:

"data":{
    "title": "hello",
    "body": "world",
    "priority": "high | normal | low"
}

To send one notification to a device:

curl --header "Authorization: key=<cloud messaging server key>" --header "Content-type: application/json" -d '{"to":"<device token>", "data":{"title":"hello","body":"world","icon":"notification_icon"}}' https://fcm.googleapis.com/fcm/send

Notification icons

  1. Generate your mono-color/transparent icons : https://romannurik.github.io/AndroidAssetStudio/icons-notification.html
  2. Import them into your project res/icon/android
  3. Add resources in config.xml to copy them in drawable as notification_icon
    <platform name="android">
    ...
        <resource-file src="res/icon/android/drawable-mdpi/notification_icon.png" target="app/src/main/res/drawable-mdpi/notification_icon.png" />
        <resource-file src="res/icon/android/drawable-hdpi/notification_icon.png" target="app/src/main/res/drawable-hdpi/notification_icon.png" />
        <resource-file src="res/icon/android/drawable-xhdpi/notification_icon.png" target="app/src/main/res/drawable-xhdpi/notification_icon.png" />
        <resource-file src="res/icon/android/drawable-xxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxhdpi/notification_icon.png" />
        <resource-file src="res/icon/android/drawable-xxxhdpi/notification_icon.png" target="app/src/main/res/drawable-xxxhdpi/notification_icon.png" />
    </platform>

see

Deploy on Google Play Store

Assuming your application is working on debug mode on your mobile device, you can push your signed APK on the play store.

Build a release APK

cordova build --release android

The unsigned APK is generated in your android directory myproject/platforms/android/app/build/outputs/apk/release/app-release-unsigned.apk

Sign your APK file

Create a keystore with your company informations:

cordova build android --release -- --keystore="path/to/keystore" --storePassword=xxxx --alias=key0 --password=xxxx

The signed APK is generated in your android directory myproject/platforms/android/app/build/outputs/apk/release/app-release.apk

Upload the APK with the play-store console

You will have to change the version each time you deliver an new APK:

See Google documentation. https://support.google.com/googleplay/android-developer#topic=3450769

Process is quite long at the very first time:

Congrats if you are still alive at this stage!

Deploy on Apple Store

Install the iOS platform

https://cordova.apache.org/docs/fr/latest/guide/platforms/ios/

You will have to do the same with iOS platform on your Mac. It is not possible to build the app on PC/Windows. iOS app requires Xcode to compile swift code and cordova plugins.

See https://cordova.apache.org/docs/en/latest/guide/platforms/ios/index.html

sudo xcode-select --install
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
npm i -g xcode
npm i -g ios-deploy
cordova platform add ios
cordova build ios

If the build is successful, launch all emulators (iPhone, iPad) to test the app.

iOS icons

The application needs many icons to target all iOS versions.

    <platform name="ios">
        <allow-intent href="itms:*" />
        <allow-intent href="itms-apps:*" />
        <icon height="180" src="res/icon/ios/icon-60-3x.png" width="180" />
        <icon height="120" src="res/icon/ios/icon-60-2x.png" width="120" />
        <icon height="60" src="res/icon/ios/icon-60.png" width="60" />
        <icon height="152" src="res/icon/ios/icon-76-2x.png" width="152" />
        <icon height="76" src="res/icon/ios/icon-76.png" width="76" />
        <icon height="80" src="res/icon/ios/icon-40-2x.png" width="80" />
        <icon height="40" src="res/icon/ios/icon-40.png" width="40" />
        <icon height="114" src="res/icon/ios/icon-57-2x.png" width="114" />
        <icon height="57" src="res/icon/ios/icon-57.png" width="57" />
        <icon height="144" src="res/icon/ios/icon-72-2x.png" width="144" />
        <icon height="72" src="res/icon/ios/icon-72.png" width="72" />
        <icon height="58" src="res/icon/ios/icon-small-2x.png" width="58" />
        <icon height="29" src="res/icon/ios/icon-small.png" width="29" />
        <icon height="100" src="res/icon/ios/icon-50-2x.png" width="100" />
        <icon height="50" src="res/icon/ios/icon-50.png" width="50" />
        <icon height="167" src="res/icon/ios/icon-167.png" width="167" />
    </platform>

Setup firebase for iOS

See all steps here:

Create the Provisioning Profile

To test your app before the final deployment in App Store, you have to sign the app thru a real iOS device (iPhone or iPad).

Deploy on the Apple store

The last step is to create the Store listing:

See https://clearbridgemobile.com/how-to-submit-an-app-to-the-app-store/

Known limitations with inAppBrowser