Hybrid Apps for BlackBerry 10: An introduction

BlackBerry 10 is leading the mobile space with its browser, receiving a near 500 score on HTML5Test and supporting cutting edge features unavailable on many other mobile platforms. This makes HTML5 a very attractive development option, and has opened the doors to combining the power of Web and Native into hybrid apps. Hybrid apps combine the versatility of HTML5 with deep integration and high frame-rates of Native Cascades apps.

There are many reasons for choosing to develop a hybrid app; personally, I find HTML5 makes it easy to work with Service APIs and display fetched content, as well as working with AJAX and JSON. On the other hand, Cascades provides the signature BlackBerry 10 Experience, boasting 60 FPS animations, deep integration with the OS and a solid set of tools for development, deployment and debugging.

This guide is tailored for both HTML5 developers who are getting started with Hybrid apps as well as Cascades developers exploring and extending their tools using the WebView component. We’ll cover setup, communication and debugging, as well as creating custom QML components that rely on a WebView.

Setup

A hybrid app contains a WebView that points to a HTML page bundled with the app, typically within the assets folder (the HTML content can be bundled remotely as well).

Here is a sample structure of a hybrid project’s assets folder:

1

2

3

4

assets/

main.qml

web/

index.html

Here’s the WebView definition:

1

2

3

4

//file: main.qml

WebView

url:"local:///assets/web/index.html"

id:webView

Communication

Communication between cascades and WebView contents is done by posting messages which is similar to communicating with Web Workers, iframes and child windows in HTML5.

1

2

3

4

//file: main.qml

webView.postMessage("hello");

//file: index.html

navigator.cascades.postMessage("hi");

Receiving messages is done by using the onMessage() and onMessageReceived() handlers in HTML5 and Cascades respectively.

1

2

3

4

5

6

7

8

9

10

11

12

//file: main.qml

WebView

url:"local:///assets/web/index.html"

id:webView

onMessageReceived:<b>function</b>()

console.log(message);//outputs "hi"

}

//file: index.html

navigator.cascades.onMessage(<b>function</b>(message)

console.log(message);//outputs "hello"

);

Aside from passing strings, developers may pass JSON objects, which need to be serialized and deserialized as the communication is strictly using strings.

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

//file: index.html

<b>var</b>contact=

name:"Bob"

age:34

//JSON.stringify will serialize the object into a string

navigator.cascades.postMessage(JSON.stringify(contact));

//JSON.parse will deserialize the string into an object, so we can access its members

navigator.cascades.onMessage(message)

<b>var</b>contact=JSON.parse(message);

console.log(contact.name);//outputs Bob

console.log(contact.age);//outputs 34

//file: main.qml

WebView

url:"local:///assets/web/index.html"

id:webView

onMessageReceived:<b>function</b>()

console.log(message);//outputs "[ object object ]"

<b>var</b>contact=JSON.Parse(message);

console.log(contact.name);//outputs "Bob"

//let's add a property and send back to WebView

contact.added=<b>true</b>;

webView.postMessage(JSON.stringify(contact));

}

window.onload

HTML5 developers are accustomed to listening to window’s onload() function before initializing the application. This ensures the document has loaded before we interact with it.

1

2

3

//file: index.html

window.onload=<b>function</b>()

App.init();

Here’s a trick that ensures your content is loaded and ready before you communicate with it from Cascades. Using the window.onload listener and postMessage(), Cascades can be notified when the WebView is ready to receive messages.

1

2

3

//file: index.html

window.onload=function()

navigator.cascades.postMessage("ready");

In Cascades, you can wait for the “ready” message before posting messages to the WebView:

1

2

3

4

5

6

7

8

9

//file: main.qml

WebView

url:"local:///assets/web/index.html"

id:webView

onMessageReceived:<b>function</b>()

<b>if</b>(message==="ready")

webView.postMessage("hi WebView!");

}

Debugging

A BlackBerry device connected to a computer and in development mode is assigned an IP address of 169.254.0.1. At the same time, the host computer is assigned 169.254.0.2. Web Inspector listens on port 1337 and above, so

1

169.254.0.1:1337

in Google Chrome while connected to the device and app open, should display Web Inspector.

Some things to note:

To find out your development IP address, go to Settings > Security and Privacy > Development Mode. The port remains the same: 1337.

Each WebView in your Cascades application will have a separate page in Web Inspector.

Live editing

Aside from debugging, Web Inspector can also be used to make live changes to the applications, which avoids repackaging and deploying the Cascades App.

This set-up requires a simple Web Server to be running on the computer. (XAMPP, etc).

Once the server is up, copy the HTML5 contents from assets into a folder in the directory that holds files to be served. (In XAMPP, default directory is c:XAMPPhtdocs).

Using a browser on the computer, navigate to

1

169.254.0.2/path/to/index.html

This should display the contents of your WebView. (If it does not, check server configuration and location of index.html and other HTML5 files).

Edit the WebView to point to this URL, instead of a local resource:

1

2

3

4

//file: main.qml

WebView

//url: "local:///assets/web/index.html"

url:"http://169.254.0.2/path/to/index.html"

Package and deploy application

Load up Remote Web Inspector on the computer

Switch to the “Console” tab.

At this point, hitting CTRL + R (or typing in window.location.reload()) will refresh the WebView (aka reload its resources from the server). This way, any changes you’ve made to the WebView content will be reflected without re-packaging and deploying the app. That’s 30 seconds every dozen minutes saved.

Once you are satisfied with the WebView, don’t forget to copy the assets back and point the WebView back to the local resources. I prefer to comment and uncomment these as needed.

Disclaimer: SDKNews.com only syndicates the blog entries from various SDK blogs.
We are not the creator/author of these entries (posts). Product names, brand names
and company names mentioned on this site may be trademarks of their respective owners.