Embed Cordova in your native iOS or Android app

Devops

Cordova

Android

While starting a new Cordova app is quite an easy process, I was a bit surprised by the difficulty to properly embed a Cordova webview into a native app. Resources on the web on this subject are not particularly easy to find and most of the time outdated. Here is a few links and explanations that should make your life easier in case you're going to embed Cordova 5+!

How does it works?

When embedding a Cordova webview, the process is to:

  1. Create a Cordova project in a folder, and add the platform(s) you need.
  2. Import the Cordova lib in your iOS or Android app
  3. Import/symlink the www folder of your Cordova app1 and the Cordova plugins code, both from platforms/<your os>.
  4. Import/symlink the config.xml located in platforms/<your os>.
  5. Create the Cordova webview inside your iOS or Android app.

In any case, your starting point should be the Cordova documentation.

At any time, to check that Cordova is properly embedded, you can take a look at the logs of your app to see if Cordova plugins are initialized.
For instance, the device plugin is installed by default on all Cordova projets. In a JS debugger, type device and if you don't see any null values, then your plugins are working.

Remember to call cordova prepare

Anytime you make changes to your JS app, the changes must be applied too in the native app. This is what cordova prepare is doing. The prepare step is also launched if you run cordova build or cordova run. If you've done only change in the JS part of the app, make sure to call cordova prepare before relaunching your app with XCode or Android Studio.

How to communicate between Javascript and the native part?

Cordova is already implementing a bridge between Javascript and the native app thanks to plugin mechanism.

Android

On Android, if you want to call native methods you have two solutions:

iOS

For iOS, it's harder to expose methods without making your own plugin. You can try to override the Cordova delegate for the webview and then redefine webView:shouldStartLoadWithRequest:navigationType: but you are likely to break Cordova things (like plugins loading or navigation) and lose a lot of time figuring this. Making your own Cordova plugin seems the best way to do things properly.

For calling Javascript from your native iOS app, stringByEvaluatingJavaScriptFromString: is the way to go.

See the documentation for UIWebView here and there

Android specificities

A more detailed step-by-step guide

Read this excellent blog article about embedding Cordova on Android.

You'll see how to include the Cordova jar (that's the step (2) of the list), make
symlinks to the www folder and plugins Java folders (step (3)), make a symlink to the config.xml from platforms/android (step (4)).

Cordova/the webview is not working when building for release

If your native Android app is using Proguard to minify/obfuscate the app, make sure you add exceptions. Otherwise, Proguard will strip the code related to the webview and in particular the JavascriptInterface methods you've declared!

See this Stack Overflow thread to exclude Cordova and related classes from Proguard stripping.

Startup performance

The webview is quickly loaded on iOS (a few milliseconds) but it's longer on Android. My solution was to create a loader in the native Android app, displayed below the Cordova webview.
If the JS framework that you're using to building your app is a bit long to load too, you may want to replicate this loader using raw CSS so that the user can see the loader while the framework is bootstrapping.

  1. You must not symlink the original www folder but the one in platforms/iosor platforms/android. This is because Cordova applies some magic on the files in platforms/.