Best Of Both Worlds: Mixing HTML5 And Native Code

Advertisement

Much has been written recently in the ongoing debate between native and HTML5 applications. There are three principal ways to develop a mobile solution:

  • native code,
  • hybrid mobile app,
  • mobile Web app.

Developing an application in HTML5 is a way to leverage code across multiple platforms, rather than having to write the entire application from scratch for each platform. As such, much of the user interface, perhaps the entire interface, would be done in HTML.

“Hybrid application” is a term often given to applications that are developed largely in HTML5 for the user interface and that rely on native code to access device-specific features that are not readily available to Web applications. Much of this native code is non-visual in nature, simply passing data back to the HTML5 layer of the app, where it is rendered to the user. Libraries such as PhoneGap1 provide this capability.

html5-native-arrows_500_mini2

Much of the debate is not about whether HTML5 is up to the task of powering a mobile application’s user experience. Mark Zuckerberg’s comments3 about some of the difficulties4 Facebook has encountered with HTML5 on mobile are well known. Some of Facebook’s issues could likely be addressed through the techniques outlined by Sencha in its Fastbook5 application and by LinkedIn in its infinite scrolling post6. Despite the latter article, LinkedIn subsequently switched directions7 towards using more native code.

Why Not Mix It Up?

Rather than build an app entirely with native or HTML5 technology, why not mix and match the technologies? With a hybrid application, building a mobile experience that leverages both native and HTML5 code for the user interface is quite possible. This enables the developer to use the most appropriate tool for the job when developing the user interface.

Clearly, developing portions of the user experience in two or more different technologies has some downsides. Chiefly, you would need developers who can handle both native development and HTML5. The portion of the user interface in native code couldn’t be readily used on other platforms and would need to be redeveloped. Given the broader scope of knowledge required by this technique and the difficulties outlined above, why would anyone want to embark on an endeavor that mixes user-interface technologies?

HTML For Rich Document Layout

Perhaps your user experience dictates that documents be displayed in the application with rich formatting. While text formatting can be accomplished on platforms like iOS with NSAttributedString, this document structure is not readily portable to other device platforms, nor does it provide the full complement of features found in HTML. If the document requires formatted content such as tables to be displayed, then a solution like NSAttributedString won’t be up to the task.

Consider the iPad application below, which was developed for a genetic sequencing company. Here we have an example of a hybrid UI:

voyager-screenshot_500_mini8
(See larger view.9)

Just looking at this application, it’s not readily apparent what has been done in native code and what portions are HTML5. Users of the application would be hard pressed to tell the difference. The document along the right side is of variable length. The table contains expandable rows, complete with CSS3 animations, and other text sections in the document vary in height as well.

Documents such as this are what HTML does best. Trying to create something like this in native code would have entailed considerably greater effort, with little benefit to the user. In this application, the HTML5 is generated with a mustache template, via the GRMustache10 library for iOS.

voyager-screenshot-shaded_500_mini11
The illustration above shows the technologies used to draw each portion of the screen. (See larger view.12)

Note that as the user scrolls up, the native document header near the top on the right dynamically resizes to show more content, thus illustrating how portions of the user interface can interact with each other. The user can tap on links and buttons in the HTML document area to pop up an internal Web viewer to load related documents. As we’ll see later in this article, creating this linkage between native and HTML experiences is relatively easy.

Desire For A “Best Of Breed” Approach

As we’ve seen, a given screen may readily mix the two technologies to provide a seamless experience. You may wish to use a native UINavigationController, with its associated UINavigationBar, on iOS, or use the action bar in an Android application. The remainder of the screen may be rendered in HTML5.

Below is an application that uses HTML5 for its shopping-cart experience, but retains the native navigation controller and tab bar for moving between pages of the workflow:

gallery-prints-1_500_mini13
(See larger view.14)

gallery-review-order_500_mini15
(See larger view.16)

Here, the HTML5 content is actually loaded from a server, and it controls the workflow throughout the experience. A defined API allows the server-supplied HTML content to modify the contents of the navigation controller bar to suit the page in the workflow.

You may find that native controls, such as MapKit on iOS, provide superior performance to what can be achieved in HTML5. In this case, your HTML5 code could communicate with the iOS native layer and ask it to present the native content over or adjacent to the HTML content.

gallery-map-pin_500_mini17
(See larger view.18)

gallery-loc-selected_500_mini19
(See larger view.20)

The examples above illustrate a native store-locator experience, displayed over top of the HTML5 workflow. Upon the user selecting a store location, the data would populate the HTML5 content, and the user would continue their workflow.

Once the user has completed interacting with the map, the results of their interaction may be passed back to the HTML5 document for further handling. Depending on how you wish to structure the application, native “widgets” may be implemented for each platform (iOS, Android, Windows, etc.) and then invoked from the common core HTML5 application. In this strategy, the HTML5 code would provide the workflow for the application, and the native content would sit in the background, waiting to provide the supplementary experience when needed.

If done properly, the user would have little indication of which portions are done in native code and which in HTML.

Ease Of App Updates

Most people are aware that in order to update the native code on an iOS or Android app, it is necessary to resubmit the application through the normal publishing channels for that platform. In the case of iOS, it can take as long as seven days to get app updates approved by Apple. This makes it more difficult to time app updates to marketing requirements and to rapidly respond to changing business needs. Exposing a portion of the user experience through HTML and JavaScript means that some of the experience can be served from the Web and thus be dynamic.

As we saw earlier, it’s possible for this Web-served content to invoke native code in your application via a “bridge” that you create. This is much the same as the bridging mechanism that allows HTML code to communicate with native code in PhoneGap via the PhoneGap plugin interface21. The example application shown earlier uses this technique. This approach was chosen chiefly so that the purchasing workflow could be altered without having to redeploy the native application. A page served from the Web may now seamlessly display a natively rendered map using whatever mapping capability is present on the device. A well-defined interface between your Web page and the surrounding native container makes this possible.

Watch That Content!

For content coming from the Web, it’s generally best to restrict the traffic that can flow over this bridge. The built-in functionality22 of something like PhoneGap provides access to a wide range of device information, some of which may be well beyond your application’s purpose. If that Web content is compromised for some reason, through something like cross-site scripting, you might suddenly find this content invoking native code in a manner you never intended.

For this reason, when bridging from Web-sourced content to native code, use your own bridge code in order to tightly control exactly what the dynamically loaded content may invoke. Some platforms have additional controls to limit what native code may be invoked from a Web view. On Android, classes must explicitly register themselves as being JavaScript-accessible23. On Android 4.2, this can be further restricted to the individual methods by adding an @JavaScriptInterface annotation on the methods that you wish to access from a Web view.

Things to consider

  • Pulling content directly from a Web server is fine if the user is online. Remember that these are mobile applications with the potential for connectivity issues. What happens if network connectivity is interrupted? Some offline capability could be retained through the use of AppCache24, but this needs to be planned for. Another approach will be covered in an upcoming section where updates to the HTML content are stored locally.
  • Hosting content on a Web server requires some infrastructure. There are now more “components” that must be considered as part of your complete app solution. It’s no longer just some native code that’s been deployed via the AppStore and potentially a set of backend services. Care must be taken that site updates do not conflict with the existing interface in the mobile applications. Keep in mind that if site changes necessitate an update to the mobile app itself, not everyone will necessarily update their copy of your app quickly, if at all. For this reason it may become necessary to version the site content so that it may be consumed with older versions of your mobile app. This is very much like the versioning built into some REST25 based interfaces in order to support compatibility with older client applications.

  • Apple takes a dim view of applications that are merely a Web view wrapped in a native app. Submissions to the iOS AppStore will likely not be approved if you’ve done nothing more than wrap some Web content in a native app. Apple expects your application will make use of some device features that cannot be otherwise accomplished in Mobile Safari. Consider if your application can benefit by integrating with the camera, contact list, local data storage, offline operation, etc. Also remember that the content served in these Web views needs to remain consistent with the original submitted intent of the application.

    If you create a word-search game and then suddenly start serving totally unrelated content in your webviews this will violate Apple’s terms and the app could be pulled from the AppStore. In accordance with the iOS developer agreement, updates may not change the primary purpose of the application by significantly altering the features or functionality of the application as submitted to the App Store.

Pushing Updates To Your App Experience

A variation on the loading of Web content as outlined above is to refresh local content with updates from the Web. In this approach, the Web content (HTML, CSS and JavaScript) is bundled on the server and downloaded to the mobile app client whenever the content is updated. This updated code can now change the user interface, application flow and so on, without the developer needing to update the app via the iOS App Store or Google Play.

Note that you can only update the HTML, CSS and JavaScript in this manner; native code cannot be updated. Apple allows JavaScript code to be downloaded and executed as long as it runs within the context of the UIWebView control in your iOS application. This is the only situation in which code “downloading” is allowed in iOS.

amway-android_500_mini26
(See larger view.27)

The application above is running on Android. The HTML content has been downloaded to the client as a bundle of content and is now being served locally. Note the use of the action bar to provide a navigation experience that is familiar to Android users. Below is the same application running on iOS, where a UINavigationController is used:

amway-ios_500_mini28
(See larger view.29)

In addition to speeding up the updating process, this manner of transmitting app changes ensures that users will be running the latest code. In the traditional approach, native app updates are distributed via an application store, and the user is informed that an update is available, although they are not required to install the latest update. Not everyone updates apps regularly. Updating local HTML, CSS and JavaScript via a dynamically deployed update bundle mitigates this issue.

The ability to dynamically update local content is actually part of a commercial hybrid mobile-development platform called Trigger.IO30. The Trigger.IO Reload31 feature permits you to push updates to the HTML portion of your application. Note that native code cannot be updated in this manner. However, if much of your application’s flow is controlled with JavaScript and augmented with native code, then making substantial changes to your application’s workflow dynamically is possible.

Keep in mind that, according to the iOS developer agreement, these updates may not change the primary purpose of the application by significantly altering the features or functionality of the application as submitted to the App Store. As such, major releases would likely still have to be carried out in the traditional manner.

Dynamically Reloading Content For Development And Testing

The ability to dynamically load updates to an app could also accelerate the development process. The native development process on both iOS and Android generally requires application code to be compiled on a desktop computer and then transferred to the device for testing. Some development programs, such as Icenium32, with its LiveSync33 and Ion34 tools, compile app updates in a cloud environment and then simply download the update to a native app that is already running on your device.

icenium-ion_500_mini35
Icenium Ion is reloading updated content. (See larger view.36)

As code changes are made and saved on the server, a simple three-finger tap-and-hold gesture will update the app on an iOS device. Icenium makes a similar capability available for Android. Adobe’s PhoneGap Build37 makes updates possible via a feature known as Hydration38. In this case, a developer can instantly reload any changes they make in their IDE39 onto a variety of devices without having to physically connect the devices to a development machine and then push the code onto the devices.

Each time the application is started with Hydration enabled, the application will check the PhoneGap Build server to see whether a new version is available. If so, the user is prompted to update to the new version. This can make quality assurance of your application easier as well. You won’t have to worry about signing code updates, provisioning and so on if the person testing your app already has the native “shell” application installed.

Be Careful

While the appeal of dynamic application updates is strong, keep in mind that for content sourced from the Web, you must implement some controls to ensure that downloaded code cannot simply call any native method in your app. Failing to do so could expose your user’s data to a third party and violate your agreement with Apple or Google. In addition, updates loaded dynamically must not significantly change the purpose or functionality of the app. Failing to adhere to this would likely result in your application being removed from the iOS App Store or Google Play. Treat these techniques as a way to enhance the user experience and to deliver bug fixes and incremental features quickly, not to thwart the App Store’s approval process.

A Bridge Between Two Worlds

Both iOS and Android offer a Web view control that you can place in a native application. In the section below, I’ll offer some code examples to illustrate how JavaScript in a Web view can communicate with native code and how native code can invoke methods on the JavaScript in the Web view.

phonegap-logo_500_mini40
(See larger view.41)

Before we look at code, keep in mind that you also have the option to use PhoneGap (Apache Cordova) within an existing application with native controls. Starting with PhoneGap 1.4 for iOS42 and PhoneGap 1.9 for Android43, placing a CordovaWebView into a native ViewController on iOS or into an activity on Android is possible. This permits your Web code to access the entire PhoneGap API and to access any PhoneGap plugins. You could, of course, follow the PhoneGap plugin API44 to expose your own native code to the CordovaWebView.

Assuming you don’t need the full capabilities of PhoneGap and you simply need to expose a small portion of functionality between the two worlds, implementing your own bridge with a relatively small amount of code is possible. The three applications referenced earlier in this document were all built in this manner using a “private API.” This further ensures that you tightly control the API that governs which portions of native functionality may be accessed by the Web view.

Bridging From iOS To A UIWebView

The UIWebView in iOS and its associated UIWebViewDelegate provide the mechanism that allows native code and JavaScript to communicate with each other. I have prepared a simple iOS application to show how a form in a UIWebView can communicate with a form in native code:

ios-bridge-example_500_mini45
(See larger view.46)

Note that the upper portion of this screen, with the light-gray background, is rendered by the UIWebView. The lower portion, with the white background, is rendered natively.

This application simply passes a JSON object from the Web view to native code, and vice versa. The code for this and an Android version are available in a GitHub repository5047.

Invoking Native iOS Code From JavaScript

My standard technique for moving data from the JavaScript to native code is to invoke a native execution method with a command name and pass along data in the form of a JSON string containing the arguments associated with the command.

var nativeBridge = {
   invoke: function (commandName, args) {
      console.log(commandName + ": " + JSON.stringify(args, null, 2));
      window.location = 'js-call:' + commandName + ':' +
                      encodeURIComponent(JSON.stringify(args));
  }
};

This code attempts to navigate the browser to a new URL, but not one with a normal http:// or file:// URL scheme. In this case, we are using a custom protocol scheme of js-call:. On the Objective-C side of things, we’ll trap this attempt to navigate in our UIWebViewDelegate:

(BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType (UIWebViewNavigationType)navigationType

Inside the delegate for this call, we can interrogate the incoming URL to see whether it’s a call from our JavaScript:

NSString *requestURLString = [[request URL] absoluteString];
    if ([requestURLString hasPrefix:@"js-call:"]) {

Now we can pull apart the request to determine the command name and the JSON arguments string:

NSArray *components = [requestURLString componentsSeparatedByString:@":"];
NSString *commandName = (NSString*)[components objectAtIndex:1];
NSString *argsAsString = [ (NSString*)[components objectAtIndex:2] stringByReplacingPercentEscapesUsingEncoding:NSUTF8StringEncoding ];

Now that we have the arguments as a string, we can turn them into an NSDictionary object:

NSError *error = nil;
NSData *argsData = [argsAsString dataUsingEncoding:NSUTF8StringEncoding];
NSDictionary *args = (NSDictionary*)[NSJSONSerialization JSONObjectWithData:argsData options:kNilOptions error:&error];

With everything decoded, it’s now simple to invoke the right native method to properly take the data that we’ve received from JavaScript and update the native UI:

if ([commandName isEqualToString:@"updateNames"]) {
   [self updateNativeNameValuesWithFirstName:[args objectForKey:@"fname"]
                                    LastName:[args objectForKey:@"lname"]];
}

When successfully handling a call via the js-call URL scheme, we must remember to return a boolean NO value from our delegate to prevent the Web view from actually trying to visit the desired URL.

Invoking JavaScript From iOS Native Code

This approach is a bit more straightforward because we don’t have to use a delegate method. We can simply call the desired JavaScript function by passing the appropriate JavaScript method’s name and required arguments as a string value to the UIWebView’s stringByEvaluatingJavaScriptFromString method.

Here, we take some values from the native view and turn them into a JSON object via an NSDictionary:

NSDictionary *namesDict = @{@"fname": self.fNameTextField.text, 
                            @"lname": self.lNameTextField.text};
NSError *error;
NSData *namesData = [NSJSONSerialization dataWithJSONObject:namesDict 
                                                    options:0 
                                                      error:&error];
NSString *namesJSON = [ [NSString alloc] initWithData:namesData
                                             encoding:NSUTF8StringEncoding] ;

Now that we have the JSON values as a string, we can simply format a command and volley it over the wall to the Web view for execution:

NSString *jsCommand = [NSString stringWithFormat:@"setNames(%@)", namesJSON];
[self.webView stringByEvaluatingJavaScriptFromString:jsCommand];

As simple as that, we’ve roundtripped between JavaScript and Objective-C. This basic technique could, of course, be leveraged to build more complex interactions.

Bridging From Android To A Web View

Below is a screenshot of the Android application running the same HTML and JavaScript code that we used in the native iOS example.

android-bridge-example_500_mini48
(See larger view.49)

As with the iOS example, the upper portion of this screen, with the light-gray background, is rendered by the Web view. The lower portion, with the white background, is rendered natively. The appearances of the iOS example and the Android example differ because we are using the default component styles for each platform. In addition, the Android example contains an action bar, which Android users would expect to find in an application.

Invoking Native Android Code From JavaScript

Android Web views have the benefit of being able to expose an entire Java class to JavaScript. There’s no need to trap an attempt to navigate off a Web view via some sort of custom URL scheme, as we did with iOS. First, we must signal to the Android Web view that it’s OK for JavaScript to execute on the Web view. I do this when loading the Web view content:

@Override
public void onStart() {
   super.onStart();
   WebSettings webSettings = webview.getSettings();
   webSettings.setJavaScriptEnabled(true);
   webview.loadUrl("file:///android_asset/webviewContent.html");
   webview.addJavaScriptInterface(new WebViewInterface(this), "Android");
}

Note the last line in the code above. We are registering a particular class, in this case WebViewInterface, to be accessed via JavaScript. In addition, this class is being namespaced by the string Android. Thus, in our JavaScript we can test whether the namespace Android is defined and, if so, invoke methods on this class, like so:

if (window.Android) {
   Android.updateNames(JSON.stringify(nameData));
}

On the Java side, the WebViewInterface is a standard Java class. If you are targeting the Android 4.2 SDK, then all methods to be exposed to JavaScript must be decorated with the @JavaScriptInterface attribute:

public class WebViewInterface {
   Context mContext;

   /** Instantiate the interface and set the context */
   WebViewInterface(Context c) {
       mContext = c;
   }

   @JavaScriptInterface
   public void updateNames(String namesJsonString) {
      Log.d(getPackageName(), "Sent from webview: " + namesJsonString);
      try {
         JSONObject namesJson = new JSONObject(namesJsonString);
         final String firstName = namesJson.getString("fname");
         final String lastName = namesJson.getString("lname");

// When invoked from JavaScript, this is executed on a thread // other than the UI thread. // Because we want to update the native UI controls, we must // create a runnable for the main UI thread. runOnUiThread(new Runnable() { public void run() { fnameEditText.setText(firstName); lnameEditText.setText(lastName); } }); } catch (JSONException e) { Log.e(getPackageName(), "Failed to create JSON object from Web view data"); } } }

Note that when the methods on this class are invoked by JavaScript, they are not executed on the main UI thread. Thus, if our intention is to update any part of the UI, we must create a new runnable and post it for execution on the main UI thread, like so:

runOnUiThread(new Runnable() {
   public void run() {
      fnameEditText.setText(firstName);
      lnameEditText.setText(lastName);
   }
});

Invoking JavaScript from native Android code is essentially similar to how we call JavaScript from Objective-C. We load the JSON representation of the data into a string and then form a JavaScript function call. One difference is that the function reference must be prefixed with the JavaScript: protocol scheme:

public void sendNamesToWebView() {
   JSONObject namesJson = new JSONObject();
   try {
      namesJson.put("fname", fnameEditText.getText().toString());
      namesJson.put("lname", lnameEditText.getText().toString());
      webview.loadUrl( "JavaScript:setNames(" + namesJson.toString() + ")" );
   } catch (JSONException e) {
      Log.e(getPackageName(), 
        "Failed to create JSON object for Web view");
   }
}

That’s all there is to roundtripping JSON data between JavaScript and native Android code. Both sample applications are available in the GitHub repository5047 for your reference.

Web Views: What’s The Downside?

Like most things in software development, there must be some caveats to developing with Web views. Keep these in mind when considering the hybrid approach and determining which portions of your application to do with which technologies.

  • Not all Web views render the same
    The capability of Web views has improved markedly in the last two years. However, your user base may not be running the latest and greatest version of Android or iOS. The Android platform has generally lagged behind the iOS platform in the capability and performance of its Web view. Google appears to be putting in a renewed effort to improve that situation, but users stuck on old versions of Android (especially releases before Ice Cream Sandwich 4.x) might find that the performance of Web views, especially those with complex layouts, do not match what is achievable on iOS. Developers will need to test the HTML5 code on Android 2.2, 2.3 and 4.x to ensure that content renders consistently. Reserve sufficient time in your project to perform adequate testing across all mobile OS versions that you intend to support.
  • Performance
    Web views are typically not as performant as native code. However, in many situations, you may find the performance to be perfectly acceptable, particularly on current hardware. Keep in mind that bridging calls between the native and Web view portions of your code will exact a performance toll. You won’t want to make calls across this bridge at sub-second intervals, but for most applications this is not an issue.
  • Scrolling behavior
    Users might be able to distinguish between the way Web views scroll and the way native portions of the app scroll. Some of this can be mitigated in new versions of WebKit with the CSS3 -webkit-overflow-scrolling: touch property. You might also wish to look at solutions such as FTScroller51 and iScroll52.
  • Complexity
    As mentioned earlier, if you will be serving some content from Web servers you must ensure you have the infrastructure necessary to support this. Because your application now spans native code, Web servers, and potentially backend services there are more points of failure. When making Web content changes you must perform backwards compatibility testing against earlier deployed versions of the application to ensure existing versions of your application still running on users devices will continue to perform as expected.
  • Developer Agreement Compliance
    Familiarize yourself with the restrictions each app marketplace might impose on content provided from the Web. As this article identified there are some notable restrictions, particularly on the iOS platform, on what your app is permitted to do with content sourced from the Web. Failure to take these restrictions into account could result in your app not being approved for release, or an existing app being pulled from the AppStore.
  • Security
    As stated earlier content sourced from the Web should be treated with some suspicion, particularly if it will be interacting with an interface to your native code. Ensure you’ve exposed only those portions of your native code that are truly required for interaction with the Web layer. Failure to do so could result in some consequences should compromised Web content be able to freely into call your native code. Make sure you take standard Web security practices into account to ensure your Web content cannot be compromised to begin with.

Given the flexibility afforded by a hybrid solution, you have the freedom to write portions of your application in native code if you find that the performance of the Web view is insufficient for a given interaction. Of course, the more native code you write, the more code will have to be rewritten for every platform you intend to support. It’s a trade-off; however, a hybrid solution puts you in control of the application’s flexibility and performance.

Summary

The use of HTML5 in mobile app development is a somewhat controversial subject. However, it’s important to understand the benefits each potential development strategy affords. As an app developer you have the ultimate decision on what strategy best suits the needs of your application. Despite some of the negative publicity that mobile HTML5 solutions have received in recent months, this article shows how HTML5 is still a valuable part of app development.

Keep performance, and security in mind when using any application development platform. Test early, and test often, across a variety of devices. As we’ve seen in this article, HTML5 brings with it many benefits that extend far beyond the convenience of sharing code across platforms. Used properly, the hybrid approach of marrying native and HTML5 code can create some truly unique and flexible solutions that would not otherwise be possible. Keep your technology choices open and flexible to reap the rewards of a hybrid experience.

(al ea)

Footnotes

  1. 1 http://phonegap.com/
  2. 2 http://www.smashingmagazine.com/wp-content/uploads/2013/10/html5-native-arrows_mini.png
  3. 3 http://techcrunch.com/2012/09/11/mark-zuckerberg-our-biggest-mistake-with-mobile-was-betting-too-much-on-html5/
  4. 4 http://lists.w3.org/Archives/Public/public-coremob/2012Sep/0021.html
  5. 5 http://www.sencha.com/blog/the-making-of-fastbook-an-html5-love-story/
  6. 6 http://engineering.linkedin.com/linkedin-ipad-5-techniques-smooth-infinite-scrolling-html5
  7. 7 http://venturebeat.com/2013/04/17/linkedin-mobile-web-breakup/
  8. 8 http://www.smashingmagazine.com/wp-content/uploads/2013/10/voyager-screenshot_mini.png
  9. 9 http://www.smashingmagazine.com/wp-content/uploads/2013/10/voyager-screenshot_mini.png
  10. 10 https://github.com/groue/GRMustache
  11. 11 http://www.smashingmagazine.com/wp-content/uploads/2013/10/voyager-screenshot-shaded_mini.png
  12. 12 http://www.smashingmagazine.com/wp-content/uploads/2013/10/voyager-screenshot-shaded_mini.png
  13. 13 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-prints-1_mini.png
  14. 14 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-prints-1_mini.png
  15. 15 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-review-order_mini.png
  16. 16 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-review-order_mini.png
  17. 17 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-map-pin_mini.png
  18. 18 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-map-pin_mini.png
  19. 19 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-loc-selected_mini.png
  20. 20 http://www.smashingmagazine.com/wp-content/uploads/2013/10/gallery-loc-selected_mini.png
  21. 21 http://docs.phonegap.com/en/3.0.0/guide_hybrid_plugins_index.md.html
  22. 22 http://phonegap.com/about/feature/
  23. 23 http://developer.android.com/guide/webapps/webview.html#BindingJavaScript
  24. 24 https://developer.mozilla.org/en-US/docs/HTML/Using_the_application_cache
  25. 25 http://en.wikipedia.org/wiki/Representational_state_transfer
  26. 26 http://www.smashingmagazine.com/wp-content/uploads/2013/10/amway-android_mini.png
  27. 27 http://www.smashingmagazine.com/wp-content/uploads/2013/10/amway-android_mini.png
  28. 28 http://www.smashingmagazine.com/wp-content/uploads/2013/10/amway-ios_mini.png
  29. 29 http://www.smashingmagazine.com/wp-content/uploads/2013/10/amway-ios_mini.png
  30. 30 https://trigger.io/
  31. 31 https://trigger.io/reload/
  32. 32 http://www.icenium.com/
  33. 33 http://docs.icenium.com/icenium-mobile-app-development/using-icenium-ion/livesync-with-ion
  34. 34 http://docs.icenium.com/icenium-mobile-app-development/using-icenium-ion/using-icenium-ion
  35. 35 http://www.smashingmagazine.com/wp-content/uploads/2013/10/icenium-ion_mini.png
  36. 36 http://www.smashingmagazine.com/wp-content/uploads/2013/10/icenium-ion_mini.png
  37. 37 https://build.phonegap.com/
  38. 38 https://build.phonegap.com/docs/hydration
  39. 39 http://en.wikipedia.org/wiki/Integrated_development_environment
  40. 40 http://www.smashingmagazine.com/wp-content/uploads/2013/10/phonegap-logo_mini.png
  41. 41 http://www.smashingmagazine.com/wp-content/uploads/2013/10/phonegap-logo_mini.png
  42. 42
  43. 43
  44. 44 http://docs.phonegap.com/en/2.7.0/guide_plugin-development_index.md.html#Plugin%20Development%20Guide
  45. 45 http://www.smashingmagazine.com/wp-content/uploads/2013/10/ios-bridge-example_mini.png
  46. 46 http://www.smashingmagazine.com/wp-content/uploads/2013/10/ios-bridge-example_mini.png
  47. 47 https://github.com/ptraeg/html5-in-mobile-apps
  48. 48 http://www.smashingmagazine.com/wp-content/uploads/2013/10/android-bridge-example_mini.png
  49. 49 http://www.smashingmagazine.com/wp-content/uploads/2013/10/android-bridge-example_mini.png
  50. 50 https://github.com/ptraeg/html5-in-mobile-apps
  51. 51 https://github.com/ftlabs/ftscroller
  52. 52 http://cubiq.org/iscroll-4

↑ Back to topShare on Twitter

Peter Traeg is a Solutions Architect at Universal Mind where he brings his broad base of technical and business consulting skills to work for our clients. With 25+ years of experience in the application development field, Peter has worked on a wide range of applications from data warehousing to online photo sharing sites. At the Eastman Kodak Company he made extensive use of Flex, AIR, HTML5, iOS, and Android technologies to help Kodak customers share their memories across a wide range of devices.

Peter is active in several development user groups where he regularly speaks on web and mobile application development technologies. When he is not experimenting with his seemingly ever growing list of mobile devices, you can find him engaging in activities such as photography, cycling, and spending time with his family in Rochester, NY.

Advertising
  1. 1

    How can you write an entire article, which include phoneGap, Icenium and Trigger.IO, but completely ignore Titanium, which offer a cross platform JavaScript environment with native “views”. I’ve done a couple of tech landscape analysis of the mobile platform and built mobile apps in HTML5, phonegap and titanium. Reading this, while comprehensive in the phonegap department, is like reading 2/3 of a book. You can talk the talk but you can’t possible walk the narrow double-edged sword of todays mobile app landscape.

    Anyhow, great phonegap article.

    -1
    • 2

      I agree with dotnetCarpenter – Titanium is an entirely different category that has been left out. The article talks about ‘native’, ‘hybrid mobile’, and ‘mobile web.’ Using that same terminology, Titanium would be ‘hybrid native.’

      It’s hybrid in that you only have to write with one codebase – everything in written in javascript. And it’s native because it ends up getting compiled down to a native app.

      Please note that Titanium does not involve using a web view, and the javascript is not run in a browser, so it is a completely different concept from phoneGap.

      0
    • 3

      You don’t need any of those and phone gap is a huge security hole.

      -1
  2. 4

    Great PhoneGap commercial, not the best UX (by far) but it gets the job done I guess. Best of breed? not sure about that.

    -2
  3. 5

    EXCELLENT article man. Dug it.

    0
  4. 6

    Mohamed Badrudeen

    October 17, 2013 9:19 am

    Great Article.

    The best approach going forward is the mix of native & hybrid. Having the whole app in native is a headache when targetting multi-platform. Similarly having the whole app in HTML5-only hybrid misses out on few functionalities that must be implemented in native.

    Basically an application should be virtually segmented into various widgets; which are wired internally to form the target app. Based on the nature of a particular widget; it should be built either as native or HTML5. Don’t forget to use a templating engine when using a HTML5 approach for a widget.

    The thumb rule is; a widget which uses the largest chunk of screen real-estate should be HTML5 based.

    0
  5. 7

    I do like all the unlimited colours, backgrounds and effects you can get with HTML5 and CSS. Also some practical programming skills in any language can be an added bonus and will always look good on any Curriculum Vitae. http://en.wikipedia.org/wiki/List_of_programming_languages

    0
    • 8

      You get the same colors with native. The only benefit Html/CSS add is write once and modify forever for each phone. Whereas native requires skilled programmers on Objective C, whereas HTML/CSS requires skilled programmers in the latter. NAtive is faster and better, but Hybrid where the responsiveness is used for native and the complexities are in web views saves you time and development and you avoid the lag HTML leaves. Native is always better, but hybrid is cheaper.

      -3
  6. 9

    Steroids.js probably has a relevant part in this discussion vis-a-vis phonegap & trigger.io …

    http://www.appgyver.com/steroids

    0
    • 10

      Agree, I totally love Steroids! It does the Hybrid UI thing described in the article like a dream.

      0
      • 11

        I totally agree. Steroids is built on top of PhoneGap and adds some awesome stuff that gives it that snappiness you expect from native like native transitions, native nav bar, tabs etc. They really have nailed the hybrid UI. AppGyver uses a multiple web view structure that really gives you control over memory issues you normally face with single page HTML5 apps.

        It also gives a wicked way of working live with your app on your devices with auto-reload as you make changes to your codebase. Unlike Trigger.io and Icenium, it’s free. They make money by charging for third party integrations.

        0
  7. 12

    Interesting article, you did left out a very important issue as was mentioned in the other feedbacks which is “Titanium”. Phonegap and other hybrid solution are also great as you specified. My biggest problem when developing a new app is finding great ready to use UX componets, because I spend way too much time and money on this process. If you know a source for such componets I would really appreciate if you will add that to your article because this is an essential part of developing apps that no one really talks about.
    How come when I come to develop a website I can find many ready to use templates but when I develop apps I can’t find any simple solutions?

    0
  8. 13

    Your base assumption is false. Kivy allows you to write Python which compiles to native code on Windows/Linux/Mac/Android/iOS. One codebase, native on all. No HTML compromise…

    http://kivy.org/#home

    0
  9. 14

    Thanks for all your comments. I wanted to address the cross-platform comments specifically. There are several reasons to consider the use of HTML5 in your mobile application. Support for cross-platform is but one of those.

    This is not an article simply about “cross platform” development. If it were, I would have included tools such as Appcelerator Titanium, Xamarin, etc. Unfortunately, the mention of ‘hybrid app’ is often immediately associated with cross-platform and the assumption is that the technology choice was made solely to achieve cross-platform capabilities. The use of HTML5 in your application certainly provides this. However there’s more to a hybrid app than this.

    Solutions which compile into native code lack the ability for code and UX to be dynamically served from an external source like a web server. They do not provide the ability for the app to receive updates to content and code which may be stored for later, offline use without going through an “AppStore” update process. Further, they lack the document flow and responsive layout capabilities of HTML and CSS. I maintain that these are some unique capabilities of a hybrid solution that should be considered by app developers.

    I should also point out that Titanium itself provides access to the web view via Titanium.UI.WebView so you can potentially leverage some of these techniques in a Titanium application. In addition, the Titanium.UI.WebView component supports communication between WebViews and Titanium itself, but with limited support for remote content.

    1
  10. 15

    Nice and Helpful…Great!!!

    0
  11. 16

    Hi! Thanks for the very interesting articule! Does anyone of you have experience submitting hybrid apps (with dynamic loaded HTML from a Webserver) to the iOS Appstore ? Regards

    0
  12. 17

    @Peter As someone who has written a simple JSON to Titanium View parser and fluid grid systems targeting iOS and Android in Titanium, I strongly disagree with your sentiment. I would even go further and claim that it is much simpler to build a JS based grid system than a CSS based one. Building a dynamic native app with JS is fairly straightforward and [I'm not the only one who has done it.](carbon.appersonlabs.com/api-documentation/)

    But as @Bob_W mentions, if you need pre written widgets etc. you really want to tap into the worlds biggest developer community – the open web. To me, this is the only valid argument for using HTML/CSS in your mobile app. With one corner case exception, if you have no control over your content.

    0
  13. 18

    EDIT: I take back my reference to Carbon. After a deeper look into the source, I realize that Carbon builds the UI at built time and not run time.

    Maybe it’s not that common to create dynamic UX in Titanium as I thought. It is pretty straight forward though.

    0
  14. 19

    A very good article thank you and very informative.

    It’s not just about scrolling speed though dotnetCarpenter. I believe there may also be latency to consider. I notice from the difficulties within the attached “Perf Feedback” nobody has asked that.

    0
  15. 20

    You won’t need to choose whether your app should be native or HTML5 as there’re lots of cloud-based services which allow making a single app that’s distributed to all major platforms such as iOS,Android and HTML5. I’m using Snappii service currently because they offer great features that can be implemented even without coding

    0
  16. 21

    Yes, HTML5 + Native is a powerful tool. I have a good example that I worked. It was a voluntary work, to create a mobile version of a magazine.

    The magazine uses custom fonts, images in between articles, and an index page. When I would make this for Android, I have to work in too much native code, change the UI font for every layout, and add images in between text flow. All that can introduce errors too.

    Suddenly I decided to check in HTML5. Just created an HTML5 template for index and contents page, and started the work. I copy-pasted all the articles easily, inserted images into the HTML, and created the index page + other files. This works very well in browser, just like the old help file that used to come with Windows Applications.

    Next, these complete HTML5 docs collection is added to the Android app’s assets, and loaded the index html page in a single WebView which filled the screen. Waaha! The app is ready and running in just ~10 lines of *native* code :-)

    In this case, I can change contents whenever I like, add links, css styles, fonts, image etc., easily and rebuild the app again, that’s all! No XMLs, no JSONs, no complex things. Just HTML5.

    This is so powerful and faster!

    1
    • 22

      That is really good to hear Vishnu. Its amazing how a webpage can be built fairly easy without too much trouble and yet be so effective at the same time. Provided of course, you get the design right.

      0
  17. 23

    Native vs cross platform app development discussions will go on for a while. I feel the choice should be made on whether your app needs to: work well in a connected environment, support deep security implementations, best exploit device features to enhance user experience. Click here to read my detailed view on the topic: http://offers.boston-technology.com/native_vs_hybrid_vs_mobileweb

    0
  18. 24

    Hi Peter,
    Thanks for this great article and for providing sample codes for iOS and Android. This is the best article that I have found on the topic of building a simple bridge between native and HTML5. You mentioned there is some performance penalty for using this technique. I am wondering, do you know of any technique that can be used to pass large blobs of binary data or very frequent calls from native to js? For example, I want to load and decode a video stream on the native side and then pass it to HTML frame by frame to render inside a canvas. Do you think that would be possible?

    0
  19. 25

    My company currently offers a hybrid app for our customers. We have developed and will be releasing a native app which will eventually be the only thing we offer, but for a few months we will have both apps in the app store. My question is what do I name the native app to distinguish it from the other one?

    0
  20. 26

    This is a marvelous article about how to use phonegap and android native and ios, i already working with this technologies and stuck in javascript to android call. I posted question regarding this in stackoverflow (http://stackoverflow.com/q/22191395/1323381), can you please check it and give an answer for me, i am facing crucial time with this.
    runOnUiThread(new Runnable() {

    @Override
    public void run() {
    // TODO Auto-generated method stub
    am.set( AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + TWENTY_SECONDS, pi );
    }
    });
    This piece of code give me NullpointerException, i add thread to handle this as you suggested, but no luck at all. Now its give me fatal error and application stop.
    Please try to answer this,i will help a lot. Thanks

    -2
  21. 27

    Here’s the same game (https://play.google.com/store/apps/details?id=hu.twofish.slice) but the modification part is it should happen on two devices like, the same screen should be shared between two devices using bluetooth and if one player moves the blade that blade shud be with some other color in other device and both of them should play… The game should be cross platform compulsorily it should be developed using html/html5/js/css.
    Can u please mail me at anoopvb18@gmail.com with sample code for bluetooth connection for android mobiles using a simple game where javascript interface should be possible?

    -3
  22. 28

    Thanks for the article. Great stuff! :)

    0
  23. 29

    Thanks for this article – very informative. It’s already bookmarked for future reference

    0
  24. 30

    On of the best articles I read in lately. It can be included easily in a book about modern development of webapps on mobile. Really good!

    0
  25. 31

    Thanks for the great article.

    You showed us how to make javascript and native to talk to each other in code.
    What’s the role of phonegap here?

    Is Phonegap…
    1. convenient wrapper of native api which javascript can use? (eg, you want to use camera? call this phonegap api)
    2. does it offer anything for the other direction? native -> javascript

    More specifically,

    I’d like to use android’s actionbar (or iphone’s navigationbar) + webview.

    I can see I can implement it using the same code you showed in your examples.
    What would I gain if I add phonegap to the mix?

    Thank you!

    0
  26. 32

    Hybrid approaches are great if you never have any intention of actually launching in the real world where you have to worry about things like cellular data networks, funnel drop-off due to latency. Oh yeah, and good luck finding a single performance monitoring platform that can seamlessly characterize use cases that span HTML5 and the native layer.

    0
  27. 33

    thanks, I believe your visitors could possibly want significantly more content pieces similar to this carry on the superior get the job done.

    0
  28. 34

    Thanks for your article.

    0
  29. 35

    Great article. I just started working on hybrid apps recently and this article has given me a good insight.

    0

Leave a Comment

Yay! You've decided to leave a comment. That's fantastic! Please keep in mind that comments are moderated and rel="nofollow" is in use. So, please do not use a spammy keyword or a domain as your name, or else it will be deleted. Let's have a personal and meaningful conversation instead. Thanks for dropping by!

↑ Back to top