Tutorial for Writing WebWorks Extension for PlayBook

by Developer on ‎06-27-2011 03:29 PM (6,252 Views)

Hi all,

 

The aim of this tutorial is to guide you through developing a custom API extension for BlackBerry® WebWorks™ for the BlackBerry® PlayBook™ tablet. This will help you explore the basic structure of BlackBerry WebWorks extensions.  Well, I'm not an expert programmer. Smiley Wink So kindly point out anything which you feel is not apt. 

 

What is an API extension? Most of you must be familiar with that. But let me take up the task to explain it in brief. An API extension is an additional feature which lets the user interact with BlackBerry PlayBook functionalities. For example, the User Interface API consists of Dialog functionality. The functionality in this object allows you to integrate standard system dialog boxes into your BlackBerry WebWorks Application and control your application flow based on user responses. This API can be accessed by adding the feature element <feature id="blackberry.ui.dialog" /> in your configuration document. For more details about APIs refer http://www.blackberry.com/developers/docs/webworks/api/ 

 

Now lets jump into our custom API extension for BlackBerry tablet.  Here I'm goin to describe how to save a normal text file to BlackBerry tablet from our app and read the content of file back in our app. I suppose most of you are eagerly waiting for the File IO API to be released at full fledge from RIM.  In the meantime you could play with this custom API extension for saving data. Smiley Happy WIth this you could write any string data into a file and read it back. But I was not able to save a blob data into the BlackBerry Playbook using the same. If anyone out here could help me with that then it would be really great.

 

You could see the existing extensions under the folder 'bbwp/ext/'. We will be adding our extension in the same folder.



Step 1: Create the files and directories following the directory structure shown in the figure.

 

extension_structure.png





Step 2: Implementing the library.xml file – This file specifies the basic structure and feature element which will be used in our application to invoke functionalities of this custom extension.

 

<?xml version="1.0" encoding="utf-8"?>
<library>
<extension id="blackberry.custom.file">
<entryClass>blackberry.custom.file.CustomFile</entryClass>
</extension>
<platforms>
<platform value="AIR">
<target version="default" config="AIR_XHR" />
</platform>
</platforms>
<configurations>
<configuration name="AIR_XHR" version="1.0" comment="For XHR architecture">
<src type="text/javascript" path="js/common/custom_file_dispatcher.js" comment="Application JS interface" />
<src type="text/javascript" path="js/common/custom_file_ns.js" comment="Application JS interface" />
<src type="text/actionscript" path="src/Air/CustomFile/src" comment="ActionScript implementation" />
</configuration>
</configurations>
<features>
<feature id="blackberry.custom.file" version="1.0.0" />
</features>
</library>

 

Step 3:  Implementing the custom_file_dispatcher.js – This file implements the basic functions that will be used to read and write data into the BlackBerry tablet. 

 

(function () {
var CUSTOM_FILE_API_URL = "blackberry/custom/file";

var ARGS_FILENAME = "filename";
var ARGS_DATA = "data";

function CustomFile() {
};

/**
* Function to read a file from application storage.
*/
function generateReadRequest(fileName) {

var remoteCall = new blackberry.transport.RemoteFunctionCall(CUSTOM_FILE_API_URL + "/readFile");
remoteCall.addParam(ARGS_FILENAME, fileName);

return remoteCall.makeSyncCall();
}

/**
* Function to write a file to application storage.
*/
function generateWriteRequest(fileName, data) {

var remoteCall = new blackberry.transport.RemoteFunctionCall(CUSTOM_FILE_API_URL + "/saveFile");
remoteCall.addParam(ARGS_FILENAME, fileName);
remoteCall.addParam(ARGS_DATA, data);

return remoteCall.makeSyncCall();
}

CustomFile.prototype.readFile = function(fileName) {
return generateReadRequest(fileName);
};

CustomFile.prototype.writeFile = function(fileName, data) {
return generateWriteRequest(fileName, data);
};

blackberry.Loader.javascriptLoaded("blackberry.custom.file", CustomFile);
})();

 

Step 4: Implementation of custom_file_ns.js 

 

(function () {

function CustomFile(disp) {

this.constructor.prototype.readFile = function(fileName) { return disp.readFile(fileName); };
this.constructor.prototype.writeFile = function(fileName, data) { return disp.writeFile(fileName, data); };

};

blackberry.Loader.javascriptLoaded("blackberry.custom.file", CustomFile);
})();

 

Step 5: Implementation of ActionScript file which interacts with the BlackBerry tablet.

 

package blackberry.custom.file
{
import flash.filesystem.File;
import flash.filesystem.FileMode;
import flash.filesystem.FileStream;
import flash.utils.ByteArray;


import webworks.extension.DefaultExtension;

public class CustomFile extends DefaultExtension
{

protected var dataFile:File;
protected var data:String;

public function CustomFile() {

super();
}

override public function getFeatureList():Array {
return new Array ("blackberry.custom.file");

}

/**
* Function to read a file from application storage.
*/
public function readFile(eFileName:String):String {

dataFile = File.applicationStorageDirectory.resolvePath(eFileName);

var bytes:ByteArray = new ByteArray();

if (!dataFile.exists){
return '';
}

var stream:FileStream = new FileStream();
stream.open(dataFile, FileMode.READ);
stream.readBytes(bytes);
data = bytes.toString();
stream.close();

return data;
}

/**
* Function to write a file to application storage.
*/
public function saveFile(eFileName:String, eData:String):Boolean {

var haveSaved : Boolean = false;
var databytes:ByteArray = new ByteArray();

dataFile = File.applicationStorageDirectory.resolvePath(eFileName);

var stream:FileStream = new FileStream();
stream.open(dataFile, FileMode.WRITE);

databytes = string2byteArray(eData);

stream.writeBytes(databytes, 0, databytes.length);
stream.close();

if (dataFile.exists){
haveSaved = true;
}

return haveSaved;
}

function string2byteArray(eString:String):ByteArray {

var byteData:ByteArray = new ByteArray();

for(var i=0;i<eString.length; i++){

byteData.writeByte(eString.charCodeAt(i));

}
return byteData;
}

}
}

 

 

Usage:

 

Now let me explain the usage of this extension in your app.

 

  • Include the feature element <feature id="blackberry.custom.file"/> in your config.xml file.
  • To read a file:
    function customRead(filePath) {
    try {
    var data = blackberry.custom.file.readFile(filePath);
    } catch(e) {
    alert("Exception in customFile: " + e);
    }
    }
  • To write data to a file
    function customWrite(filePath, fileData) {
    try {
    if(blackberry.custom.file.writeFile(filePath, fileData)){
    alert('success');
    }else {
    alert('failure');
    }
    } catch(e) {
    alert("Exception in customFile: " + e);
    }
    }

 

 

Thats it folks Smiley Very Happy