
For almost a year developers have been using the Flex Toolkit for Apex to build Rich Internet Application on salesforce.com's Force.com platform. Today Adobe and Salesforce are announcing the new Force.com Toolkit for Adobe AIR and Flex. This new toolkit extends the existing capabilities of the Flex Toolkit for Apex and adds offline data synchronization for Flex applications running on the desktop with Adobe AIR.
Developers already using the Flex Toolkit can easily plug in the new offline synchronization functionality with minor code changes. For instance, to begin using the offline data sync in a project using the older toolkit simply replace the “Connection” object with the new “AIRConnection” object. When using AIRConnection offline data sync happens automatically – query results are automatically saved to the local SQLite Database and when disconnected creates, updates, and deletes are all tracked and then committed to Salesforce when the application returns online. Those new to the toolkit can follow the simple tutorial at the end of this article to get started building offline applications on Force.com.
In version 1.0 of the toolkit queries must be written in such a way that they are compatible with both SOQL (the Salesforce Object Query Language) and standard SQL. Also for version 1.0 of the toolkit queries must be single table queries.
To begin using the toolkit follow these steps:
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:airforce="http://www.salesforce.com/air"
creationComplete="initApp()" horizontalScrollPolicy="off" status="{airConnection.connected ? 'Online' : 'Offline'}">
<mx:Script>
<![CDATA[
import com.salesforce.objects.SObject;
import com.salesforce.results.QueryResult;
import com.salesforce.AsyncResponder;
import com.salesforce.objects.LoginRequest;
ᅠᅠprivate function initApp():void
{
var lr:LoginRequest = new LoginRequest({
username: "<your username>",
password: "<your password>",
callback: new AsyncResponder(function (result:Object):void {
getContacts();
})});
airConnection.login(lr);
}
ᅠᅠprivate function getContacts(o:Object=null):void
{
airConnection.query("Select Id, FirstName, LastName From Contact", new AsyncResponder(
function (qr:QueryResult):void {
dg.dataProvider = qr.records;
}));
}
]]>
</mx:Script>
ᅠᅠ<airforce:AIRConnection id="airConnection"/>
ᅠᅠ<mx:DataGrid id="dg" width="100%" height="100%"/>
ᅠᅠ<mx:HBox>
<mx:Button label="Get Contacts" click="getContacts()"/>
<mx:Button label="Create New Contact">
<mx:click>
var acc:SObject = new SObject('Contact');
acc.FirstName = 'Test';
acc.LastName = 'Contact ' + (new Date()).time;
airConnection.create([acc], new AsyncResponder(
function (result:Object):void
{
getContacts();
})
);
</mx:click>
</mx:Button>
<mx:Button label="Force Offline" click="airConnection.forceNetworkStatusChange(false)" enabled="{airConnection.connected}"/>
<mx:Button label="Force Online" click="airConnection.forceNetworkStatusChange(true)" enabled="{!airConnection.connected}"/>
</mx:HBox>
</mx:WindowedApplication>
ᅠ
ᅠ
Lets take a closer look at the code used in the example above to see how the toolkit works.
ᅠ<airforce:AIRConnection id="airConnection"/>
ᅠ
The AIRConnection is responsible for handling all of the offline functionality as well as passing requests through to the underlying Connection object which facilitates the communication to Salesforce. Developers building web applications should use the Connection object instead of AIRConnection.
ᅠ
ᅠᅠᅠᅠvar lr:LoginRequest = new LoginRequest({
username: "<your username>",
password: "<your password>",
callback: new AsyncResponder(function (result:Object):void {
getContacts();
})});
airConnection.login(lr);
ᅠ
Whether online or offline the user must login. When offline the password is not validated but the username must match the username which was logged in when the online query was made.
ᅠ
ᅠᅠᅠᅠairConnection.query("Select Id, FirstName, LastName From Contact", new AsyncResponder(
function (qr:QueryResult):void {
dg.dataProvider = qr.records;
}));
ᅠ
The same query statement us used for offline and online queries. The AIRConnection decides whether to perform the query against Salesforce (when online) or against the local SQLite Database (when offline). When online the query results are automatically saved to the local database.
ᅠ
ᅠvar lr:LoginRequest = new LoginRequest({
username: "<your username>",
password: "<your password>",
callback: new AsyncResponder(function (result:Object):void {
getContacts();
})});
airConnection.login(lr);
ᅠ
By default the toolkit detects network connectivity and handles those events automatically. As a convenience to developers the toolkit also allows the connection status be set explicitly. Applications can obtain the current connection status through the AIRConnection's connected property. Applications can also listen for the networkStatusChanged event on AIRConnection to be notified when the connection status changes.
ᅠ
ᅠᅠᅠᅠᅠᅠvar acc:SObject = new SObject('Contact');
acc.FirstName = 'Test';
acc.LastName = 'Contact ' + (new Date()).time;
airConnection.create([acc], new AsyncResponder(
function (result:Object):void
{
getContacts();
})
);
ᅠ
The create, update, and delete operations are performed the same way whether online or offline. AIRConnection decides whether to send those operations to Salesforce.com immediately (when online) or defer them until network connectivity is regained.