Hanging on the telephone

JBoss goes mobile: Mobile applications with Aerogear

Aerogear is a JBoss Community project which puts the emphasis on mobile development, providing a library and various utilities for Android, iOS and JavaScript. We’re going to take a whistle stop preview tour in this article (originally published in JAX Magazine).

The development of mobile applications does not necessarily need to be over-complicated. A common hurdle faced is the deployment of an application on different platforms. For Java developers, Android still seems to be the most common platform choice. At the same time, developers can expect several issues that are completely different to those of Swing or even Enterprise Java applications. New or additional languages, such as JavaScript or Objective-C, can also cause problems.

Different frameworks

Dealing with the completely different frameworks that exist for their respective platforms is a considerably bigger problem than working with various languages. The central aim of a mobile application is to implement business requirements, but this means putting it into source code. To access a HTTP interface in Android, the "HttpURLConnection" API is frequently used - however, in iOS applications,  the AFNetworking Framework [1] or the native NSURLConnection class [2] is most commonly utilised. For mobile web applications, jQuery or the XmlHttpRequest object is used. These frameworks have completely different APIs, and not only because they were created in different programming languages. These differences serve to make it easier to program a business requirement for different mobile platforms.

Aerogear: Uniform API

The Aerogear project [3] provides a unified API for Android, iOS, and JavaScript. The concepts of the library are platform specific and therefore easy to transfer to other platforms. In practice, this means that the API provides the same functionality, but honors the realities of the programming language. For example, in Java a callback is expressed by an interface, and in Objective-C, a so-called block is used (comparable with a closure). The current focus of Aerogear lies in HTTP communication, offline storage, and various security issues such as OTP [4] or authentication.

HTTP REST Access

For access to RESTful web services, Aerogear offers the pipe interface. It abstracts the actual HTTP access to an HTTP resource, and is essentially CRUD - functionality. All pipe objects are created by the pipeline class, which also takes over the management of the individual pipes. Let us pretend there is a REST service, http://server.com/cars, that works with the corresponding CRUD functionality, as described in [5]. Get the code for the Aerogear Android platform [6] here:

//set up the baseURL and the Pipeline „Factory“:

URL baseURL = new URL(„http://server.com“);

Pipeline pipeline = new Pipeline(baseURL);



// create Connection to „http://server.com/cars“

Pipe carsPipe = pipeline.pipe(Car.class);

In the first three rows, the pipe object for the URL is created. Then data can be read from the REST service or transmitted to it (Listing 1).

Listing 1

// create “business object”

Care someCar = new Car(.........);

// save, via HTTP POST:

carsPipe.save(someCar, new Callback<Car>() {



@Override Public void onSuccess (Car serverData) {

// work with the Data...

}

@Override Public void onFailure (Exception E) {

show error...

}

});



End

A simple POJO object is sent using the save method to the server. The fact that internal HTTP POST is used is completely transparent. In addition to the actual object, an anonymous implementation of the callback interface is passed. In case of a successful saving (eg HTTP 201 (created)), the onSuccess () method is called. Various errors are signaled within onFailure ().

If this code is loaded from an Android activity or a fragment, you should make sure to pay attention to the properties of the Android Activity Lifecycle [7].When a call is transferred, the application in the background, and (via HTTP) read data can be lost, or even cause an error if the callback of the UI wants to change the background located ligand Android Activity. The same happens with a "change in configuration", as for example, turning on the phone. The latest Android Activity is destroyed, and the operating system creates new data. The data of the anonymous callback implementation is also lost. Again, Aerogear offers assistance in the form of special abstract helper implementations of the callback interface [8].

In addition to the CRUD features we have also tackled the issue of hypermedia: AeroGear‘s pipe supports various types for scrolling through large amounts of data ("pagination"). Among other things, the Web Linking RFC is implemented [9] (see Listing 2).

Listing 2

…

ReadFilter readFilter = new ReadFilter();

readFilter.setLimit(2);max.two cars per response



//HTTP GET for two cars

carsPipe.read(readFilter new Callback<List<Car>>(){



@Override

Public void onSuccess (List<Car>) response;

PagedList<Car>pagedCars = (PagedList<Car>)response;



// performs HTTP-GET for next items

data.next(....callback.....);



}@Override

public void onFailure (Exception e) {

//show error

}

});



End

For the pagination, the read()-method is supplied with the usual callback as well as a Read Filter object [10]. In addition to these parameters, additional fine-tuning for the production of the can with the pipe object class PageConfig [11] are specified, such as the information which Linking variant to be used (for example, RFC 5988, or within the response).

If the server responds to the (HTTP) request from the Android application, the onSuccess() method is loaded, as expected. Here the list result is made on a type-cast to a PagedList object. The call to next () intends to send another request to the server. In this example, the next two cars will be loaded from the server.

Apple iOS

The above described Pipe-/Pipeline-API is also for the iOS platform before [12]. Here, too, the pipe object known read or save functions, but adapted to the "peculiarities" of Objective-C (Listing 3).

Listing 3

//set up the baseURL and the Pipeline “Factory”:

NSURL *baseURL = [NSURL URLWithString:@http://server.com”};

AGPipeline *pipeline = [AGPipeline pipelineWithBaseURL:baseURL];



// create Connection to “http://server.com/cars”

id<AGPipe> carsPipe = [pipeline pipe:^(id<AGPipeConfig) {

[config setName:@”cars”]’

}];

End

Within a few lines of the pipe object for the requested URL is created. As in the Android version, the pipeline "Factory" features a pipe method. Here is a so-called block (similar to Java Closures (JDK8)). This block gets passed exactly to determine the configuration (eg EndpointName or authentication modules) an object. Then data can be read from the REST service or transferred to it.

Similar to the Android Version of a "Car", an object is sent to the server. Instead of a separate class, a map is used, which represents the car. The success and failure callbacks are also implemented using block. Both blocks have exactly one argument.

Xcode template

The starting new projects is often idle. In Aerogear there is therefore an Xcode template[13], shown in Figure 1

Figure 1: Xcode template

This template creates a simple example based on the Aerogear iOS library. After the project is created, we‘re just missing a small step: The dependencies must be installed with CocoaPods [14].CocoaPods is broadly comparable to Apache Maven:

pod install

With this call, the dependencies are loaded and a so-called workspace is created. After this workspace, open the application can be run directly on your own phone.

In addition to Android and iOS, JavaScript is also available for mobile web applications. Again, the API meets the previously introduced concepts. JavaScript functions are used here for callbacks, however:

Offline storage

Various client platforms offer different ways to store data:

  •  Android: Memory, SQLite

  •  iOS: Memory, PList

  •  JavaScript: Memory, Session Storage, Local Storage

Again, the Store API provides cross-platform concepts, in turn, adapted to the specificities of the programming language used, as here in the case of JavaScript:

In addition to an ordinary login modules Aerogear provides support for One Time Password (OTP), see [15] . With the 2-phase authentication, the actual login, expanded by an additional protection mechanism. Besides the password, the user selected a generated OTP token is required. Aerogear in the TOTP (Time-based One-Time-Password) variant isimplemented [16] . The Java library can be both client side (Android) and are also used on the server side. The server generates a secret and sends it to the client:

The client must now based on the received mystery, for example, via SMS, the token for the second step of the registration form (Android):

The client sends this token to the server now, so this - after successful validation - the login attempt are free:

Figure 2 shows the process based on the iOS client demos [17]. A JavaScript version is currently in progress.

Figure 2: iOS client demo

AeroGear.NEXT

The current version 1.0 provides the basis for future Aerogear features. Currently, the developers are working on new features such as "Data-Sync", "Offline" (eg Core Data for iOS or content provider stores for Android) as well as cross-platform push notifications which for APNs [18], GCM [19] or Simple Push [ 20]. The Aerogear Unified Push Server provides a single HTTP interface (and Java API) to a push notification to be sent to different devices (Fig. 3) [21].

Figure 3: Push notification

A special feature here is the development of a JavaScript API for Simple Push, which is available outside the FirefoxOS. In addition to the JavaScript library, the project provides an implementation of the Simple push protocol.

Matthias Wessendorf works as Principal Software Engineer at Red Hat, where he is focused on mobile and HTML5. In the past he was the PMC Chair of the Apache MyFaces project. Matthias is a regular conference speaker. He maintains a blog (http://matthiaswessendorf.wordpress.com) and tweets (@mwessendorf).

Matthias Wessendorf

What do you think?

Comments

Latest opinions