Introduction to Apache Cordova
Apache Cordova is an open-source mobile development framework that allows you to build cross-platform mobile applications using standard web technologies (HTML, CSS, and JavaScript). Cordova wraps your web application in a native container, providing access to native device features through a consistent JavaScript API. This cheatsheet provides essential commands, configurations, and best practices for Cordova development.
Setup & Installation
System Requirements
- Node.js (LTS version recommended)
- Git
- Platform SDKs:
- Android: Android Studio, Java JDK, Gradle
- iOS: Xcode (Mac only), CocoaPods
- Windows: Visual Studio
Installation Commands
# Install Cordova CLI globally
npm install -g cordova
# Check installation
cordova -v
# Update Cordova
npm update -g cordova
Project Management
Creating Projects
# Create a new project
cordova create path/to/project [app-id [app-name [config]]]
# Examples
cordova create MyApp
cordova create MyApp com.example.myapp "My App"
cordova create MyApp --template cordova-template-framework7
Platform Management
# Check available platforms
cordova platform ls
# Add platforms
cordova platform add android
cordova platform add ios
cordova platform add browser
# Remove platform
cordova platform rm android
# Update platform
cordova platform update android
# Check platform requirements
cordova requirements android
Build Process
# Build all platforms
cordova build
# Build specific platform
cordova build android
cordova build ios
# Release build for Android
cordova build android --release -- --keystore=path/to/keystore --storePassword=password --alias=alias_name --password=key_password
# Clean builds
cordova clean
cordova clean android
Testing & Emulation
# Run on connected device
cordova run android
cordova run ios
# Run with specific target
cordova run android --target=Pixel_3a_API_30
# Run on emulator
cordova emulate android
cordova emulate ios
# Run with live reload (hot reload)
cordova run android --live-reload
cordova run browser --live-reload
Plugin Management
Core Plugins
| Plugin | Purpose | Add Command |
|---|---|---|
| cordova-plugin-camera | Camera access | cordova plugin add cordova-plugin-camera |
| cordova-plugin-device | Device information | cordova plugin add cordova-plugin-device |
| cordova-plugin-file | File system access | cordova plugin add cordova-plugin-file |
| cordova-plugin-geolocation | GPS location | cordova plugin add cordova-plugin-geolocation |
| cordova-plugin-inappbrowser | In-app browser | cordova plugin add cordova-plugin-inappbrowser |
| cordova-plugin-network-information | Network status | cordova plugin add cordova-plugin-network-information |
| cordova-plugin-splashscreen | Splash screen control | cordova plugin add cordova-plugin-splashscreen |
| cordova-plugin-statusbar | Status bar control | cordova plugin add cordova-plugin-statusbar |
Plugin Management Commands
# List installed plugins
cordova plugin ls
# Add a plugin
cordova plugin add cordova-plugin-camera
# Add plugin with specific version
cordova plugin add cordova-plugin-camera@5.0.1
# Add plugin from GitHub
cordova plugin add https://github.com/apache/cordova-plugin-camera.git
# Remove plugin
cordova plugin rm cordova-plugin-camera
# Update plugin
cordova plugin update cordova-plugin-camera
Configuration
config.xml Essential Elements
<!-- App identification -->
<widget id="com.example.myapp" version="1.0.0">
<name>My App</name>
<description>My Cordova Application</description>
<author email="dev@example.com" href="https://example.com">Developer Name</author>
<!-- Content source -->
<content src="index.html" />
<!-- Preferences -->
<preference name="DisallowOverscroll" value="true" />
<preference name="SplashScreenDelay" value="3000" />
<preference name="KeyboardDisplayRequiresUserAction" value="false" />
<preference name="Orientation" value="portrait" />
<!-- Platform specific settings -->
<platform name="android">
<!-- Android specific preferences -->
<preference name="AndroidWindowSplashScreenAnimatedIcon" value="res/screen/android/splash.png" />
</platform>
<platform name="ios">
<!-- iOS specific preferences -->
<preference name="scheme" value="app" />
<preference name="hostname" value="localhost" />
</platform>
<!-- Icons and splash screens -->
<platform name="android">
<icon src="res/icon/android/icon-36-ldpi.png" density="ldpi" />
<icon src="res/icon/android/icon-48-mdpi.png" density="mdpi" />
<!-- more icon definitions -->
<splash src="res/screen/android/splash-land-hdpi.png" density="land-hdpi" />
<splash src="res/screen/android/splash-port-hdpi.png" density="port-hdpi" />
<!-- more splash screen definitions -->
</platform>
<!-- Plugins -->
<plugin name="cordova-plugin-camera" spec="~5.0.1" />
<plugin name="cordova-plugin-statusbar" spec="~2.4.3" />
<!-- Access origins - network security -->
<access origin="*" />
<allow-intent href="http://*/*" />
<allow-intent href="https://*/*" />
<!-- more allow-intent definitions -->
</widget>
Common Preferences
| Preference | Description | Values |
|---|---|---|
SplashScreenDelay | Splash screen duration in ms | Number (e.g., “3000”) |
ShowSplashScreenSpinner | Show loading spinner | “true” or “false” |
FadeSplashScreen | Fade animation for splash screen | “true” or “false” |
Orientation | Screen orientation | “default”, “portrait”, “landscape” |
FullScreen | Hide status bar | “true” or “false” |
BackgroundColor | App background color | Color hex (e.g., “#FFFFFF”) |
KeyboardDisplayRequiresUserAction | Auto display keyboard | “true” or “false” |
StatusBarOverlaysWebView | Status bar overlay | “true” or “false” |
StatusBarBackgroundColor | Status bar color | Color hex (e.g., “#000000”) |
JavaScript API Examples
Device Information
document.addEventListener('deviceready', onDeviceReady, false);
function onDeviceReady() {
console.log('Running on: ' + device.platform);
console.log('Device model: ' + device.model);
console.log('Device version: ' + device.version);
console.log('Device UUID: ' + device.uuid);
console.log('Cordova version: ' + device.cordova);
}
Camera
function takePicture() {
navigator.camera.getPicture(onSuccess, onFail, {
quality: 50,
destinationType: Camera.DestinationType.FILE_URI,
sourceType: Camera.PictureSourceType.CAMERA,
encodingType: Camera.EncodingType.JPEG,
mediaType: Camera.MediaType.PICTURE,
allowEdit: true,
correctOrientation: true
});
}
function onSuccess(imageURI) {
var image = document.getElementById('myImage');
image.src = imageURI;
}
function onFail(message) {
alert('Failed because: ' + message);
}
Geolocation
function getLocation() {
navigator.geolocation.getCurrentPosition(
onLocationSuccess,
onLocationError,
{
maximumAge: 3000,
timeout: 5000,
enableHighAccuracy: true
}
);
}
function onLocationSuccess(position) {
var latitude = position.coords.latitude;
var longitude = position.coords.longitude;
console.log('Latitude: ' + latitude + ', Longitude: ' + longitude);
}
function onLocationError(error) {
console.log('code: ' + error.code + ', message: ' + error.message);
}
File System
function writeFile() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
fs.root.getFile('myfile.txt', { create: true, exclusive: false }, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function() {
console.log('Write completed.');
};
fileWriter.onerror = function(e) {
console.log('Write failed: ' + e.toString());
};
var blob = new Blob(['This is some text'], { type: 'text/plain' });
fileWriter.write(blob);
});
});
});
}
function readFile() {
window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function(fs) {
fs.root.getFile('myfile.txt', {}, function(fileEntry) {
fileEntry.file(function(file) {
var reader = new FileReader();
reader.onloadend = function() {
console.log('Read completed: ' + this.result);
};
reader.readAsText(file);
});
});
});
}
Network Information
function checkConnection() {
var networkState = navigator.connection.type;
var states = {};
states[Connection.UNKNOWN] = 'Unknown connection';
states[Connection.ETHERNET] = 'Ethernet connection';
states[Connection.WIFI] = 'WiFi connection';
states[Connection.CELL_2G] = 'Cell 2G connection';
states[Connection.CELL_3G] = 'Cell 3G connection';
states[Connection.CELL_4G] = 'Cell 4G connection';
states[Connection.CELL] = 'Cell generic connection';
states[Connection.NONE] = 'No network connection';
console.log('Connection type: ' + states[networkState]);
}
// Listen for online/offline events
document.addEventListener("online", onOnline, false);
document.addEventListener("offline", onOffline, false);
function onOnline() {
console.log('Device is online!');
}
function onOffline() {
console.log('Device is offline!');
}
In-App Browser
function openExternalLink(url) {
var ref = cordova.InAppBrowser.open(url, '_blank', 'location=yes');
ref.addEventListener('loadstart', function(event) {
console.log('Start loading: ' + event.url);
});
ref.addEventListener('loadstop', function(event) {
console.log('Stop loading: ' + event.url);
});
ref.addEventListener('loaderror', function(event) {
console.log('Error loading: ' + event.url);
});
ref.addEventListener('exit', function(event) {
console.log('Browser closed');
});
}
Status Bar
function configureStatusBar() {
// Hide the status bar
StatusBar.hide();
// Or show it
StatusBar.show();
// Change background color
StatusBar.backgroundColorByHexString("#33000000");
// Make status bar text color
StatusBar.styleLightContent(); // Light text for dark backgrounds
StatusBar.styleDefault(); // Dark text for light backgrounds
}
Splash Screen
function controlSplashScreen() {
// Hide splash screen
navigator.splashscreen.hide();
// Show splash screen (typically not needed)
navigator.splashscreen.show();
}
Event Handling
Lifecycle Events
// Device ready - fundamental Cordova event
document.addEventListener('deviceready', onDeviceReady, false);
// Pause event - app sent to background
document.addEventListener('pause', onPause, false);
// Resume event - app brought to foreground
document.addEventListener('resume', onResume, false);
// Back button press (Android)
document.addEventListener('backbutton', onBackButton, false);
// Menu button press (Android)
document.addEventListener('menubutton', onMenuButton, false);
// Volume buttons
document.addEventListener('volumeupbutton', onVolumeUp, false);
document.addEventListener('volumedownbutton', onVolumeDown, false);
// Low memory warning
window.addEventListener('cordovaCriticalMemoryWarning', onMemoryWarning, false);
function onDeviceReady() {
console.log('Cordova is ready!');
// Initialize your app here
}
function onPause() {
console.log('App paused');
// Pause app activities, save state
}
function onResume() {
console.log('App resumed');
// Resume app activities, refresh data
}
function onBackButton() {
// Handle back button - prevent default if needed
// e.g., show exit confirmation or navigate back in your app
}
function onMemoryWarning() {
console.log('Low memory warning!');
// Clean up resources, cache, etc.
}
Performance Optimization
Best Practices
Minimize DOM manipulation
// Bad: Multiple DOM manipulations for (var i = 0; i < items.length; i++) { document.getElementById('list').innerHTML += '<li>' + items[i] + '</li>'; } // Good: Single DOM update var html = ''; for (var i = 0; i < items.length; i++) { html += '<li>' + items[i] + '</li>'; } document.getElementById('list').innerHTML = html;Use CSS3 animations instead of JavaScript when possible
.animated-element { transition: transform 0.3s ease-in-out; } .animated-element.active { transform: translateX(100px); }Event delegation for dynamic content
// Instead of attaching events to each button document.getElementById('container').addEventListener('click', function(e) { if (e.target && e.target.className == 'my-button') { // Handle button click } });Optimize images
- Use appropriate formats (JPEG for photos, PNG for UI elements)
- Resize images to needed dimensions before including in app
- Consider using SVG for icons and simple graphics
Network optimization
// Cache data locally function fetchData() { var cachedData = localStorage.getItem('myData'); var cachedTimestamp = localStorage.getItem('myDataTimestamp'); var now = new Date().getTime(); // Use cache if less than 1 hour old if (cachedData && cachedTimestamp && (now - cachedTimestamp < 3600000)) { return Promise.resolve(JSON.parse(cachedData)); } else { return fetch('https://api.example.com/data') .then(response => response.json()) .then(data => { localStorage.setItem('myData', JSON.stringify(data)); localStorage.setItem('myDataTimestamp', now); return data; }); } }
Debugging Techniques
Console Logging
// Basic logging
console.log('App initialized');
console.info('Information message');
console.warn('Warning message');
console.error('Error message');
// Object inspection
console.log('User object:', userObject);
// Timing operations
console.time('dataLoad');
loadData().then(() => {
console.timeEnd('dataLoad');
});
Remote Debugging
Android: Chrome DevTools
- Enable USB debugging on device
- Connect device to computer
- In Chrome, navigate to
chrome://inspect/#devices - Select your app to open DevTools
iOS: Safari Web Inspector
- Enable Web Inspector on device (Settings > Safari > Advanced > Web Inspector)
- Connect device to Mac
- In Safari, enable Develop menu (Preferences > Advanced)
- Select your device and app from Develop menu
Other Debugging Tools
- Weinre: Remote debugger for older devices
- GapDebug: Visual debugging tool
- Ripple Emulator: Chrome extension for Cordova simulation
Security Best Practices
Content Security Policy
<!-- In index.html -->
<meta http-equiv="Content-Security-Policy"
content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval';
style-src 'self' 'unsafe-inline';
media-src *;
connect-src 'self' https://api.example.com">
Secure Storage
// Use secure storage plugin for sensitive data
document.addEventListener('deviceready', function() {
var ss = new cordova.plugins.SecureStorage(
function() {
console.log('Success: SecureStorage initialized');
// Store data
ss.set(
function(key) { console.log('Set ' + key + ' successfully'); },
function(error) { console.log('Error setting ' + error); },
'mySecretKey', 'mySecretValue'
);
// Retrieve data
ss.get(
function(value) { console.log('Retrieved: ' + value); },
function(error) { console.log('Error retrieving ' + error); },
'mySecretKey'
);
},
function(error) { console.log('Error initializing SecureStorage: ' + error); },
'my_app_storage'
);
}, false);
HTTPS Connections
// Always use HTTPS for API calls
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error));
Publishing Guide
Android
Generate signing key (one-time setup)
keytool -genkey -v -keystore my-key.keystore -alias my_key_alias -keyalg RSA -keysize 2048 -validity 10000Create release build
cordova build android --release -- --keystore="path/to/my-key.keystore" --storePassword="store_password" --alias="my_key_alias" --password="key_password"Alternative: Build using build.json
{ "android": { "release": { "keystore": "path/to/my-key.keystore", "storePassword": "store_password", "alias": "my_key_alias", "password": "key_password", "keystoreType": "jks" } } }cordova build android --releaseAPK Location:
platforms/android/app/build/outputs/apk/release/app-release.apk
iOS
Create release build
cordova build ios --releaseOpen in Xcode
open platforms/ios/MyApp.xcworkspaceIn Xcode:
- Select appropriate target
- Set device to “Generic iOS Device”
- Product > Archive
- Use Organizer window to validate and distribute your app
Resources
Official Documentation
Debugging Tools
UI Frameworks for Cordova
This cheatsheet provides a comprehensive reference for Apache Cordova development, covering essential commands, configurations, and best practices to help you build cross-platform mobile applications efficiently.
