Oracle Blog

Simplifying Enterprise Mobility

Thursday Feb 12, 2015

Oracle Mobile Application Framework (MAF) v2.1.0
uses Cordova version 3.6.3 on Android and 3.7.0 on iOS to provide access to native
device functionality. The MAF 2.1.0 extension
to JDeveloper 12.1.3 enables you to easily include any of the hundreds of published 3rd
party Cordova plugins into your MAF app.

But what if you can’t find a suitable 3rd
party plugin? You could elect to write
your own, which, depending on the functionality required, may not be as
difficult as you think.

In this post I’ll provide an introduction
to developing a Cordova plugin by creating a very simple plugin for each of
Android and iOS.

How
does a Cordova plugin work?

In a nutshell, Cordova provides a bridge
between JavaScript and native code, enabling you to write native code that gets
exposed to your app via a common JavaScript interface.

Each method exposed by a plugin’s
JavaScript interface is mapped to a method in the plugin’s native code via the Cordova
bridge, which also enables you to pass parameters back and forth between the
JavaScript and native methods.

What
comprises a Cordova plugin?

A Cordova plugin typically consists of:

Native code for each supported
platform

A common JavaScript interface

A manifest file called plugin.xml

The conventional structure for a Cordova
plugin supporting both Android and iOS is:

Ideally, community-published plugins also
include release notes, author and license information, and a README file.

A plugin may also include additional native
resources and these are identified in the plugin.xml manifest file. This manifest file is read by the plugman command-line tool, which is used
by the Cordova command-line interface and also by the MAF extension for
JDeveloper.

In some rare cases, a plugin may be created
that simply executes some native code on initialization and requires no
JavaScript interface.

JavaScript that provides the interface for calling your plugin from within a Cordova-based app, such as a MAF app.

Native code that provides the
functionality you need. Since MAF
supports both Android and iOS, you should write native code for both platforms.

A plugin.xml manifest
file that defines your plugin and how plugman
should incorporate it into a MAF app (or any Cordova-based app).

What
tools do I need to create my own custom Cordova plugin?

You really only need a text editor to
create your own custom Cordova plugin, which is all I’ve used to create the
custom plugin described in this post.

For more complex plugins, you may wish to develop
and test the plugin’s native code in each platform’s native IDE, which means
downloading and installing the Android Studio and/or Apple’s Xcode.

You don’t need Cordova installed to develop
a Cordova plugin. Once you have
developed your Cordova plugin, you can incorporate it directly into your MAF
app for testing. However, if you wish to
test your plugin within a Cordova app, you must download and install Cordova
using the Cordova
Command-Line Interface.

How
do I write the plugin’s JavaScript interface?

We start with the JavaScript interface
since it provides a common interface to both the Android and iOS native
code. This interface effectively defines
what is required in the native code.

The JavaScript interface must call the cordova.exec method to invoke a native plugin method, as follows:

This call invokes the action
method on the service class on the native side, passing the arguments in the optional args
array. If the native code completes
successfully, the successCallback function is executed, along with any return parameters. If the native code fails, the failureCallback function is executed, with an optional error parameter. For more information on JavaScript callback
functions, refer to this
helpful blog post by Michael Vollmer.

Let’s create a very simple plugin that
displays a native popup dialog. Thus
plugin shall present one method that takes 3 parameters – title, message and
button label – and shall return the result in the ‘success’ callback. No ‘failure’ callback will be
implemented. The service class shall be
named “Alert” and we shall call the sole method “alert”.

The Alert class should be
part of a package that will be referenced in the manifest file, plugin.xml.

The Alert class must
extend the CordovaPlugin class, the definition of which you can find here.

The Alert class must
override the execute method, since this will be called each time the JavaScript cordova.exec method is called, providing the name of the plugin method, the
input parameters and a callback context.
The execute method should return true if a valid
action was passed in, otherwise false.

Once the code has completed, it should
return a result and optional return parameters to the calling JavaScript by
invoking the sendPluginResult method on the callbackContext object. Returning
a result of PluginResult.Status.OK will cause the
JavaScript ‘success’ callback to be executed.
Any other result (apart from PluginResult.Status.NO_RESULT) will cause the JavaScript
‘failure’ callback to be executed.

In our plugin, a ‘success’ result is
returned when the user taps the button on the popup dialog and a value of 0 is
returned.

The Alert class may
override the pluginInitialize method if any initialization logic is required when the plugin is
first constructed.

Save this code into a file called Alert.java,
within a src/android subfolder of your plugin’s top-level folder.

For more detailed information on aspects such a threading and
event handling, refer to the Cordova page Android
Plugins.

iOS

For our example, we must define a class
called Alert in an Objective-C source file called Alert.m and
corresponding header file Alert.h.

Once the code has completed, it should
return a result and optional return parameters to the calling JavaScript by
invoking the sendPluginResult method on the commandDelegate object. Returning a result of CDVCommandStatus_OK will cause the
JavaScript ‘success’ callback to be executed. Any other result will cause the JavaScript ‘failure’ callback to be
executed.

In our plugin, a ‘success’ result is
returned when the user taps the button on the popup dialog and a value of 0 is
returned.

The Alert class may implement
the pluginInitialize method if any initialization logic is required when the plugin is
first constructed.

Save this code into a file called Alert.m, within a src/ios subfolder of your plugin’s top-level folder.

For more detailed information on aspects such a threading and
event handling, refer to the Cordova page iOS
Plugins.

How
do I write the plugin’s manifest file (plugin.xml)?

The manifest file, called plugin.xml,
is an XML document that defines the plugin and tells plugman how to incorporate the plugin into your MAF app (or any
Cordova-based app) for each platform it supports.

The plugin element must
contain the plugin’s XML namespace (xmlns), id and version.

The name and description elements should always be defined.
If you intend to publish your plugin for public use, you should include
additional elements such as those identifying the author, license, keywords and
repository.

The child elements of the engines
element define which version(s) of the Cordova framework the plugin
supports. Since this plugin has been
developed based on Cordova 3.6.0 documentation and will be tested within a MAF
2.1.0 app, we should set the minimum required Cordova version to 3.6.0.

The JavaScript interface is defined by
including a js-module tag for each JavaScript file.
Any file defined here is automatically copied into your MAF app and
injected into any HTML using a <script> tag so that you don’t have to specifically add this tag yourself,
or include the JavaScript as content in your AMX features. The clobbers tag indicates that the module
shall be inserted into the window object as Alert, so your MAF app code should call the JavaScript method Alert.alert to execute the plugin’s alert method.

If your plugin has a dependency on another
Cordova plugin, you can define this using a dependency tag. Since our plugin does not have any
dependencies, there is no such tag defined.

The platform tag is used
to define the platforms that are supported by the plugin. Within each platform tag, you
specify the native source files, changes required to configuration files, any
additional native resources or frameworks and any platform-specific JavaScript
files.

For Android, it is important to specify the
full package name of the plugin as the value for the android-package parameter, for example “com.acme.plugin.alert.Alert”, and to specify
the target-dir for any source files (since this indicates the location to which
the source file should be copied and it must match the package name), for
example “src/com/acme/plugin/alert”.

Save this XML into a file called plugin.xml, within your plugin’s top-level folder.

Conclusion

We have now developed a custom Cordova
plugin that can be incorporated into a MAF 2.1.0 app, or any app based on
Cordova 3.6.0 or above. In a follow-up
post [Edit: here], I’ll describe how to integrate this plugin into a MAF app.

For developers looking for more detailed
information about how to create a Cordova plugin, refer to the Cordova
Plugin Development Guide, which contains specific guides for each native
platform.

Thursday Jan 24, 2013

JavaScript debugging is a critical functionality when skinning the application, as you can interactively test out CSS commands interactively while the application is running in the simulator. For example, you can enter a new color in a style class in the debugging window in the Safari browser on your Mac, and see the color change in the simulator as soon as you enter it. The entire setup requires using Safari b

Unfortunately, Safari 6 broke compatibility with the JavaScript debugging capabilities. If you are on Lion or prior Mac OS, you can at least downgrade to 5.x Safari to enable JavaScript debugging. Safari 5 is not available on Mountain Lion. If you are using Mountain Lion Mac OS, then you will need the following combination of software to support JavaScript debugging:

Xcode 4.5.x

iOS Simulator version 5.1

There are some known issues with using iOS simulator version 6.0 and therefore not recommended.

Please note that the ADF Mobile application will run fine on devices running on iOS 6, as long as it's compiled using the iOS 5.1 SDK.

Safari 6

The steps to configure and setup Xcode 4.5 with iOS simulator 5.1 is as follows:

Click on the Download tab. The Downloads tab loads and show you options to install iOS 5.1 and 5.0 simulators. Click to install the iOS 5.1 simulator.

After the download/installation is complete, go back to JDeveloper. Select menu item Tools - Preferences - ADF Mobile - Platforms -iOS. In the iOS SDK Simulator directory, make sure you select the Simulator version 5.1 that you have just installed. Please make sure you re-select this path specifically.

Deploy the application to the simulator. The ADF Mobile app would deployed to the 5.1 simulator, although 6.0 simulator would be started by default. This is because JDeveloper relies on Apple Script to start the iOS Simulator, and 6.0 simulator is the default. This means you will not see the app in the 6.0 simulator.

You will need to switch to the 5.1 simulator by going to menu Hardware - Version 5.1. You will then see your application running in the simulator as expected

Now, to enable JavaScript debugging, you will need to:

Set
the following properties in cvm.properties file in your ADF Mobile application workspace (under Application Resources Panel in JDeveloper):

#
JavaScript debugging settings

javascript.debug.enabled=true

#
Specifies the feature that will trigger the activation of the JavaScript
debugging

javascript.debug.feature=<feature
id>:9999

Deploy
the application and navigate to the amx page to be inspectedAccess
the http://localhost:9999 URL in a Safari
browser to view the list of AMX pages in the App.

Select
the link corresponding to the page displayed in the simulator to inspect the
DOM for the page or debug JavaScript.

That's it! You can then interactive change the style classes in the Safari browser window, and see ADF Mobile App's UI change in real time.

Please let us know if you encounter any issues, and hope this helps to debug some of the skinning challenges you have encountered.

About

This blog is is dedicated to announcements,tips and tricks and other items related to developing, integrating, securing, and managing mobile applications using Oracle's Mobile Platform. It is created and maintained by the Oracle Mobile product development team.