I have previously written about how we used the Salesforce Touch Platform to build Cloud Hunter – the scavenger hunt mobile app for Dreamforce 2012. This is the second installment of a series where I dissect the application architecture and code. I covered the application use case, high level architecture and some of the base Visualforce/Apex code in the first post (the full codebase is available in this GitHub repo). In this post I’ll cover how I converted the Visualforce-based web version of Cloud Hunter into a hybrid application using the Salesforce Mobile SDK.
Before getting to the ‘how’, let’s briefly review the ‘why’. As I had described in my previous post, we wanted to support Cloud Hunter on both Android and iOS, but didn’t want to create two separate native applications. Creating a pure web application using the Touch Platform (primarily Visualforce and Apex) was attractive to us because of the develop-once-run-anywhere advantage of a mobile web app as well as the ability to reuse existing developer skills (namely, HTML5, JavaScript and CSS3). However, Cloud Hunter required access to device functions like the camera that is not currently possible with pure HTML5 applications. Enter hybrid mobile apps, which put a thin native ‘wrapper’ around a web application giving you all the benefits of web mobile development combined with access to device features like the camera, contacts database, accelerometer and more.
Creating a Hybrid app for Cloud Hunter
This wiki article details the steps for creating Android and iOS hybrid applications from a Visualforce page. That article however assumes that your starting point is the ContactExplorer sample project that ships with the Mobile SDK. I followed the following steps in order to create a hybrid Android application from scratch for Cloud Hunter. You’ll need Ant 1.8.0 or later, Eclipse, Android SDK (r20 or above) and Android Development Tools (ADT) plugin for Eclipse (r20 or above) installed and configured in order to follow these steps.
p.s. You can get the equivalent steps for creating a hybrid iOS application from the wiki article referenced earlier
- Depending on your target mobile platform, download and install the Android and/or iOS Mobile SDK on your local computer. Start by doing a git clone of the SDK project.
Next, run the install.sh script.
- Next, create a new hybrid Android project by running the following command from the root directory of the Salesforce Mobile SDK (i.e. SalesforceMobileSDK-Android)
As the name implies, the create_hybrid_vf Ant target generates a new Android project that ‘wraps’ an existing Visualforce page. The parameters correspond to :
- appName: the name for the new application
- targetDir: the directory where the generated code should reside
- packageName: the java package for the new Android app
- apexPage: the starting Visualforce page for the application. In the case of Cloud Hunter, that is GameList
- Next, import the newly created project into Eclipse. You can do so by selecting File -> Import -> General -> Existing Projects into Workspace in Eclipse.
- The Mobile SDK implements OAuth 2.0 under the covers so that developers don’t have to worry about the low-level ‘plumbing’ necessary to authenticate and connect to Salesforce. In order for the authentication to work however, you’ll need to create a new Connected App (formerly known as a Remote Access App) in your Salesforce Org. The new Connected App will require you to specify a callback URL and will in turn be assigned a unique Consumer Key, both of which we’ll need in the next step.
- In the imported Eclipse project, open the assets->www->bootconfig.js file. Set the remoteAccessConsumerKey variable to the Consumer Key that was assigned in the previous step. Set the oauthRedirectURI variable to the redirect URL that you specified when creating the new Connected App (e.g. ‘cloudhunter:///oauth/callback’).
And with that, we have an Android version of Cloud Hunter. As you can see from the steps listed above, creating a hybrid application using the Mobile SDK is dead simple and best of all requires minimal knowledge of the target mobile platform (Android or iOS). As with Cloud Hunter, the vast majority of your development is done in Visualforce/Apex using standard web technologies like HTML5 and JavaScript and the Mobile SDK takes care of creating the thin native shell around that web application. You can even list the resulting hybrid application(s) on the respective App Stores (Apple App Store and Google Play), as we did for Cloud Hunter.
Using PhoneGap (aka Cordova) in Cloud Hunter
As mentioned earlier, accessing device functions like the camera are one of the reasons we created hybrid versions of Cloud Hunter. The critical piece of technology that enables device access in a hybrid application is an open source project called Apache Cordova (also referred to as PhoneGap). Cordova/PhoneGap exposes device functions like the Camera and microphone as JavaScript functions. Your web application is rendered in a custom WebView and Cordova provides a JavaScript<–> Native ‘bridge’ that translates between the JS code and the equivalent native device APIs. The Salesforce Mobile SDK bundles Cordova and all you have to do is to import the Cordova JavaScript library in your Visualforce page.
If only it were that simple for Cloud Hunter! We created hybrid versions of Cloud Hunter for both Android and iOS – i.e. the same set of Visualforce pages were ‘wrapped’ into two separate hybrid apps. However, the Cordova JS library is specific to the target platform and so we needed to import different JS files in the Visualforce page depending on the platform running the application (Android or iOS). Enter Dynamic Visualforce Components, which let you insert dynamic markup into a VF page based on some runtime logic that is written in the Apex controller/extension class. Here is a small snippet from the Mission VF page that shows the details about a particular mission and lets players complete it. Line 6 shows how the PhoneGapJS component will be dynamically added to the page DOM at runtime.
And here is a small snippet from the extension class
In the extension, we’re determining the target mobile platform based on the User Agent HTTP header. We then dynamically inject the appropriate version of the Cordova/PhoneGap JavaScript library (both of which have been added as Static Resources) using the Apex equivalent (Component.Apex.IncludeScript) of an <apex:includeScript> tag.
Now that we’ve created a hybrid version of Cloud Hunter and included the PhoneGap/Cordova JS library in our page, how can we implement some of the core features of the application, namely taking a picture, scanning a QR/Bar code, capturing a signature and checking-in at a designated location. That will be the subject of my next post in the series. To be continued….