While developing hybrid mobile apps

Hybrid apps bring together the best elements of native and HTML5 apps. Minimistically, HTML content wrapped within a native launcher, hybrid apps are best suited for quick development, reasonably good UX, easier maintainability and most importantly access to native functionality. Also, it is relatively easier to port a hybrid app to several mobile platforms when compared to native apps – since the most of the UI (HTML) layer remains same across platforms.

There are popular frameworks one can use to develop hybrid apps for e.g. Phonegap, Titanium, Intel XDK, etc. However, if you want to get your hands dirty and work on your own native/Js code to exchange data and trigger js/native events, here are couple of things that would get you started with hybrid apps on popular mobile platforms.

The Windows Phone SDK provides WebBrowser component to render HTML content. It provides the function Navigate(String/URI) to load HTML content. Once the HTML DOM has been loaded, the native code can invoke any javascript functions. It also allows to invoke the javascript functions with arguments – this is how native objects can be shared with javascript functions.

For example, the following snippet invokes a javascript function from C# native code. It also passes data (text) as parameters to the javascript function.

1
2
3
4
function MyJSFunction(text) {  console.log(text);}
 
String text = "Text to pass to JS";
wb.InvokeScript("MyJSFunction", text); // wb is an instance of WebBrowser

There’s also a way to send data objects from Javascript to native C# functions. The ScriptNotify handler would catch all the window.external.notify(obj) calls from javascript. This could be handy when fetching any user inputs from the HTML UI. Here’s one example showing how this works to fetch the browser’s user agent from Javascript.

1
2
3
4
5
6
7
8
9
10
11
WebBrowser wb = new WebBrowser();
wb.IsScriptEnabled = true;	
 
// window.external.notify passes value to C# code
wb.NavigateToString("&lt;html&gt;&lt;script&gt;window.external.notify(navigator. userAgent);&lt;/script&gt;&lt;/html&gt;<script type="text/javascript"><!--mce:0--></script>");
 
wb.ScriptNotify += (sender, eventargs) =&gt;
	{
		data = eventargs.Value;
	};
// check http://pastebin.com/WvWaRqt1 if the above snippet is messed up

On Android, there’s a similar WebView component to render HTML. Sharing native objects with javascript becomes easy by the WebView.addJavascriptInterface method. Triggers can be passed to the native code through the shared objects as well. It is also possible to pass javascript objects to native code. Here’s an example,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class JSObject{
Vector mCars;
	public void allotCars(Vector cars)
	{
	mCars = cars;
	}
	public int getNumOfCars(){
		return mCars.size();
	}
	public Car getCar(int index){
		return mCars.elementAt(index);
	}
	public void EventfromJavascript(){
		TriggerEvent(); // function in android class that triggers an event
	}
	public void DatafromJavascript(int data){
		ProcessData(data); // function in android class that processes data
	}
}
 
JSObject myObject = new JsObject();
// populate myObject
 
myObject.allotCars(cars); // cars is a Vector list of car object
 
WebView mWV = new WebView();
mWV.getSettings().setJavaScriptEnabled(true);
 
// exposing myObject as 'carObject' for javascript
mWV.addJavascriptInterface(myObject, "carObject");

From javascript,

1
2
3
4
5
6
7
8
9
10
11
// fetches number of car objects
var number = carObject.getNumOfCars();
 
// calls EventfromJavascript java function
carObject.EventfromJavascript();
 
// passes data from javascript to java/android
carObject.DatafromJavascript(data);
 
// fetches thumbnail image of the first car
icon = carObject.getCar(0).getThumbnail(); // getThumbnail is a member function of Car object

While developing hybrid apps for iPhone/iPad one could use the UIWebView. Javascript functions can be triggered by the stringByEvaluatingJavaScriptFromString function. stringByEvaluatingJavaScriptFromString is similar to InvokeScript function on the Windows Phone platform and allows to pass parameters to the javascript functions. However, it can be called slightly better since it also allows to return values from the javascript functions.

1
2
3
4
5
6
7
8
9
10
// JS function
function MyJSFunction(text)
{
 alert(text);
 //... for example, return value of a HTML text input element
 return lineEdit.value;
}
 
// Calling, passing arguments and returning values between obj-C and JS
NSString *returnvalue = [webView stringByEvaluatingJavaScriptFromString:[NSString stringWithFormat:@"MyJSFunction('%@')",str]];

There’s one limit however on using this function. The JavaScript execution time is limited to 10 seconds for each top-level entry point. If your script executes for more than 10 seconds, the webview stops executing the script. This is likely to cause trouble.

Enough code… What can these triggers and data exchange methods be used for is upto your imagination – you may use it to access native features like senors, advanced camera functions, launching other apps, switching apps from foreground to background, persistent data storage, making an intuitive UI, etc.

Image credits: http://www.noser.com
This entry was posted in Mobile apps and tagged , , , , , , , , , , . Bookmark the permalink.

Comments are closed.