
VIPS Field Observation App
Providing an easy way to register pest observations made in the field by registered VIPS users. Available for Android and iOS smartphones.
Architecture
The app has been built using
- Apache Cordova v.12.0.0
- Vue.js version 2 and vue-cli
Most of the UI has been built in vue, and then compiled to the cordova www folder, and then subsequently used to build for the smartphone platforms.
Prerequisites: node, npm, vue-cli and cordova
Make sure you have the correct versions of npm and nodejs Use nvm to install, here's how to install nvm in the first place
Then run:
nvm install --lts
sudo npm install -g @vue/cli --unsafe-perm
sudo npm install -g cordova@12.0.0 --unsafe-perm
Build Setup (vuejs)
You need to add your local configuration file before you do this. The file's name must be src/components/CommonUtilLocal.vue
, and here's example content:
<script>
export default {
CONST_URL_DOMAIN: "https://logic.vips.nibio.no",
CONST_DEBUG: false,
};
</script>
Then you can install the dependencies and run the test web server
# install dependencies
npm install
# serve with hot reload at localhost:8080 - only for testing view layer
npm run dev
# build for production with minification - before building with Cordova
npm run build
# build for production and view the bundle analyzer report
npm run build --report
For a detailed explanation on how things work, check out the guide and docs for vue-loader.
Build/emulate with cordova
# Add browser, android and ios platforms
cordova platform add browser
cordova platform add android
cordova platform add ios
# Test in browser
cordova emulate browser
# Test on Android. Requires correct setup of the Android SDK.
# Read more here: https://cordova.apache.org/docs/en/latest/guide/platforms/android/index.html
cordova emulate android
# Test on IOS. Install Xcode from Mac AppStore, and the iOS Simulator
cordova emulate ios
Troubleshooting Android platform builds
- If you upgrade cordova or change the package name of the app (in config.xml),
you should reset the platform, using
cordova platform remove android
and thencordova platform add android
Error message when starting the Android emulator
(When running cordova emulate android
)
Command failed with exit code 1: apkanalyzer manifest target-sdk /home/[...]/vipsobservationapp/platforms/android/app/build/outputs/apk/debug/app-debug.apk
Exception in thread "main" java.lang.NoClassDefFoundError: javax/xml/bind/annotation/XmlSchema
This can be solved by installing the Android command-line tools, as per these instructions, see screen shot below:
Connecting to a local server
While developing, you will want to connect to a local instance of VIPSLogic. This is done by editing the property CONST_URL_DOMAIN
in /src/components/CommonUtilLocal.vue
. Set it to whatever domain name you wish (e.g. vipslogic-local.no) and then edit your /etc/hosts
file to point this to the IP address 10.0.2.2, like this
10.0.2.2 vipslogic-local.no
Test on an Android phone
After running npm run build
, you can find the Android package (.apk
) in /platforms/android/app/build/outputs/apk
.
By connecting your Android phone to your computer and copying the file to your phone, you can install it on the phone. This
depends on you having enabled developer mode on your phone. How to do that differs a great deal, so search the interwebs for
how to do it.
Develop the code
Don't touch the /www folder!
Normally in Cordova you would put your code here, but this is where vue-cli is putting the things that it builds.
Where to update app version
-
/package.json
(Updates version in the Settings/About section in the app) /config.xml
Main template
The main layout is based on a very simple template snatched from Bootstrap. You find it in /html (at the project root level).
Everything that Vuejs operates on happens inside the main
element
<main id="app" role="main" class="container"></main>
You find all the Vuejs code in the /src
folder
Looking at /src/main.js, the Vue app is not started until Cordova fires the deviceready event.
The router components (the "pages" in the Single Page Application that you manage) are found in /src/components
. The router (paths + components definitions) is found in /src/router/index.js
Checking out new code
Remember to always run npm install
after checking out new code from the repository. That way, new dependencies will be installed.
Translation
This tutorial has been used to enable translation.
I couldn't get the per-component translation thing working (where you embed it in <i18n>
tags),
so all translations go into the /locales/[languagecode].json
files.
There's a simple translation example in /src/components/PlacesList.vue
:
<template>
<div>
<!-- ... -->
<div class="alert alert-info">
<button type="button" class="close" data-dismiss="alert" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
{{ $t("placeslist.explanation") }}
</div>
<!-- ... -->
</template>
Change the startup language in the app here in /i18n.js
:
export default new VueI18n({
locale: process.env.VUE_APP_I18N_LOCALE || "nb", // Here you can customize
fallbackLocale: process.env.VUE_APP_I18N_FALLBACK_LOCALE || "en",
messages: loadLocaleMessages(),
});
To translate in JavaScript, refer as this.$i18n.t
, e.g.:
lstPOI.push({
pointOfInterestId: "undefined",
name: this.$i18n.t("mapobservation.label.noPOIselected"),
});
Adding Internationalization
npm install vue-i18n --save
Troubleshooting
Error when running cordova emulate android
If seeing this error message
adb: failed to install [...]/vipsobservationapp/platforms/android/app/build/outputs/apk/debug/app-debug.apk: Failure [INSTALL_FAILED_VERSION_DOWNGRADE]`
...The easiest way to fix it is to wipe the emulator for data, using this command:
emulator -avd Pixel_3a_API_30_x86 -wipe-data
Replace your emulator name with the example above
Android publishing
Before building, signing and publishing, make sure you bump the version in package.json
{
"name": "vipsobservationapp",
"version": "0.9.7",
"private": true,
"description": "The Field Pest Observation App for VIPS users",
"author": "Tor-Einar Skog <tor-einar.skog@nibio.no>",
"scripts": {
"build": "node build/build.js",
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"i18n:report": "vue-cli-service i18n:report --src './src/**/*.?(js|vue)' --locales './src/locales/**/*.json'",
"start": "npm run dev"
},
...and in config.xml
<?xml version='1.0' encoding='utf-8'?>
<widget id="no.nibio.vips.observation" version="0.9.7"
xmlns="http://www.w3.org/ns/widgets"
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:cdv="http://cordova.apache.org/ns/1.0">
For NIBIO, a signing key was originally created sometime in 2021, but it has been lost. After contacting Google Play Developer Support, we received instructions for how to generate a new key (example code):
keytool -genkeypair -alias upload -keyalg RSA -keysize 2048 -validity 9125 -keystore keystore.jks
...so we did this, and stored the keystore securely (in a dev project folder)
We then extracted the PEM to send to Google (example code)
keytool -export -rfc -alias upload -file upload_certificate.pem -keystore keystore.jks
Signing can be done like this (example):
$ cordova build android --release -- --keystore=[PATH_TO_KEYSTORE] --storePassword=[KEYSTORE_PASSWORD] --alias=upload --password=[PASSWORD] --packageType=bundle
If building the bundle using the above command does not result in a signed bundle, it can be signed after it has been created, using this command
jarsigner -verbose -keystore keystore.jks app-release.aab upload
You can verify this by using this command:
jarsigner -verify -verbose -certs app-release.aab
Notes and docs
Developer account for Google Play
https://stackoverflow.com/questions/69357694/unable-to-build-app-bundle-aab-in-cordova
https://cordova.apache.org/docs/en/11.x/guide/platforms/android/plugin.html
https://developer.android.com/guide/app-bundle
https://developer.android.com/studio/publish#unknown-sources
iOS Publishing
On iOS, do the regular npm run build
, and then cordova build ios
. You should then be ready to run the app in a simulator or a real device in XCode. Remember that in order to run it on a real device, you must sign it (see XCode screenshot below) with either your personal team account (for debug only) or a company account for distributing to App Store.
Distributing
In XCode, click Product -> Archive
, and then select the latest build and Distribute. Click all sorts of yesses and hope for the best.
Versioning
You set the main version in /config.xml
and package.json
(in the source code, before building for iOS) - that's what's going to show in TestFlight/App store.
However, you can update the build in TestFlight without changing the common source code, you can do this in XCode.