James Ward

Created

15 October 2007

Requirements
     
Prerequisite knowledge
Required products Sample files  

To benefit most from this article, you should have a working knowledge of Flex and AIR.

Flash Builder (Download trial)

Adobe AIR

salesforce_sample.zip (993 KB)
 
User level      
Intermediate      
 
Adobe Flex Builder and Adobe AIR make it easy to build dynamic rich Internet applications (RIAs). For organizations looking to use these technologies to build secure, scalable, reliable business applications, the salesforce.com Apex platform provides a ready-made infrastructure. The Apex platform for custom application development provides a foundation for business applications to use on-demand building blocks like customer relationship management (CRM) and sales force automation (SFA).
 
With Apex, Flex developers can use salesforce.com as a back end for Flex applications and bypass the hassles of setting up an application server, database, and the rest of the back-end infrastructure. Salesforce.com also provides support for authentication, transactions, and a host of other capabilities that would otherwise have to be developed as part of the server-side application.
 
In this tutorial you will learn how to build a simple desktop AIR-based application that uses Apex to access the salesforce.com infrastructure. Although this tutorial focuses on AIR, the application could also be built on Flex and accessed inside a web browser. You will be using Flex Builder to code the application.
 
Add a new project in Flex
Figure 1. Add a new project in Flex
 
  1. Accept the default output folder and click Next.
  2. In the next page of the dialog box (for setting build paths), select the Library path tab and click Add SWC....
  3. To add the salesforce.com SWC to the Library Build Path, enter the local path to the as3Salesforce.swc file from the Adobe Flex Toolkit for Apex, such as "E:/as3Salesforce.swc" (see Figure 2).
  4. Click Finish.
Add an individual SWC file to the build path
Figure 2. Add an individual SWC file to the build path
 
In the new project you just created there is a file named sf_air.mxml that contains the following code:
 
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"> </mx:WindowedApplication>

 
Writing the AIR application

The following is the entire Flex code for the AIR application. You can copy and paste it directly into sf_air.mxml, or you can follow along with the steps below to build it up from the default code.
 
Note: Be sure to replace the <username> and <password> in the doLogin() function with your Force.com Developer Edition username and password.
 
<?xml version="1.0" encoding="utf-8"?> <mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:salesforce="http://www.salesforce.com/" creationComplete="doLogin();"> <mx:Script> <![CDATA[ import com.salesforce.objects.LoginRequest; import mx.controls.Alert; import com.salesforce.results.QueryResult; import com.salesforce.AsyncResponder; private function doLogin():void { var lr:LoginRequest = new LoginRequest(); lr.username = "<username>"; lr.password = "<password>"; lr.callback = new AsyncResponder(loginResult, loginFault); conn.login(lr); } private function loginResult(result:Object):void { conn.query("SELECT Id, Contact.Firstname, Contact.Lastname FROM Contact", new AsyncResponder(queryResult)); } private function loginFault(fault:Object):void { Alert.show("Login error!"); } private function queryResult(qr:QueryResult):void { dg.dataProvider = qr.records; } ]]> </mx:Script> <salesforce:Connection id="conn"/> <mx:DataGrid id="dg" width="100%" height="100%"/> </mx:WindowedApplication>
The first step is to add the salesforce.com XML namespace:
 
xmlns:salesforce="http://www.salesforce.com/"
In the code, any tags that are prefaced with the namespace "salesforce" will be able to instantiate components in that namespace. For example, the following line instantiates a Connection object:
 
<salesforce:Connection id="conn"/>
I also remove layout="absolute" from the WindowedApplication tag so the application will default to the vertical layout.
 
Next, add the creationComplete event to the WindowedApplication tag:
 
creationComplete="doLogin();"
The creationComplete event is thrown when the application is initialized. In this case, I call the function doLogin(), which issues a login request to salesforce.com.
 
The doLogin() function is defined in the script block, which begins:
 
<mx:Script> <![CDATA[ import com.salesforce.objects.LoginRequest; import mx.controls.Alert; import com.salesforce.results.QueryResult; import com.salesforce.AsyncResponder;
The import statements import the classes that will be used in the ActionScript below. The three lines that begin with "import com.salesforce…" refer to the objects in the salesforce.com SWC file.
 
 
The application uses the LoginRequest and connection objects to initiate salesforce.com authentication.
 
Note: Be sure to replace the <username> and <password> in the doLogin() function with your Force.com Developer Edition username and password.
 
private function doLogin():void { var lr:LoginRequest = new LoginRequest(); lr.username = "<username>"; lr.password = "<password>"; lr.callback = new AsyncResponder(loginResult, loginFault); conn.login(lr); }
The LoginRequest object is populated with a username, password, and a new AsyncResponder. The AsyncResponder provides the connection with a reference to a function (or functions) to call back once it obtains results. After setting up the login request, the code calls the login()method of the Connection object.
 
 
The username and password in the sample code were assigned to Adobe developers who registered with saleforce.com for a development account. You can use them to run the application in this tutorial. A real-world application, of course, would prompt the user for this information instead of hard coding it.
 
The function loginResult() will be called following a successful authentication, and loginFault() will be called if the authentication fails.
 
private function loginResult(result:Object):void { conn.query("SELECT Id, Contact.Firstname, Contact.Lastname FROM Contact", new AsyncResponder(queryResult)); }
This function also uses the Connection object. Specifically, loginResult() calls the query() method providing a query string, and another new AsyncResponder object to handle the results. Though the syntax of the query string resembles SQL, it is actually Sforce Object Query Language (SOQL). This call performs a query on the salesforce.com back end, and designates queryResult() as the function to handle the results. The code leaves any errors that may occur on this call to be handled by the default fault handler.
 
 
The next function, loginFault(), simply displays an alert to notify the user if the login is unsuccessful:
 
private function loginFault(fault:Object):void { Alert.show("Login error!"); }
The final ActionScript function is queryResult(), which is called back when the query is completed.
 
private function queryResult(qr:QueryResult):void { dg.dataProvider = qr.records; }
The QueryResult object passed to queryResult() is defined in the salesforce.com SWC and is imported like the AsyncResponder object.
 
This function simply sets the dataProvider of the DataGrid defined later to the array of records returned by the query.
 
The DataGrid is defined by the line:
 
<mx:DataGrid id="dg" width="100%" height="100%"/>

 
Saving, running, and exporting the AIR application

After you choose File > Save, you build the AIR application by choosing Project > Build Project. If you have previously selected "Build Automatically" on the Project menu, Flex Builder will automatically build the application when you save it.
 
To test the application, choose Run > Run sf_air. You can also right-click (Windows) or Control-click (Mac OS) sf_air.mxml in the navigation pane, and select Run Application (see Figure 3).
 
The sf_air main application window
Figure 3. The sf_air main application window
 
If you want to allow someone else to run this application, you can distribute it as a standalone AIR application. Right-click (Windows) or Control-click (Mac OS) on the project, select Export..., then select Flex > Export Release Version. Follow the wizard steps to complete the process of creating your AIR file. You can then e-mail or post the exported file, sf_air.air, on the web for others to use. As long as they have AIR installed, they can run the application locally on their system.
 

 
Where to go from here

In addition to AIR, there are two other ways to distribute an application like sf_air. Both of the methods require creating the Flex project as a web application, rather than a desktop application. The actual code would be almost identical; however, instead of using WindowedApplication as the root tag, you would use Application.
 
Once you build the Flex application, you can deploy the application into the salesforce.com system as an S-control so that it shows up on one of your web pages on salesforce.com. You could then direct your users to salesforce.com where they would have access to the application you built.  Alternatively, you can deploy the Flex application on your own website.
 
This application illustrates a simple query that displays a list of available records, but you can use Flex and Apex to build much more powerful salesforce.com applications that include inserts, updates, and multiple tables as well as applications that use the extensive Apex workflow and transaction APIs.
 
You can also use this simple application as a starting point for exploring Flex and Apex further. For example, you can modify the application to allow the user to double-click a First Name for more information. To do this, you would add a double-click event handler to the data grid. That event handler would perform a different query based on the item that was clicked on. The results from that query could then be displayed in a new window. That functionality can be incorporated in the same MXML file. As the application becomes more sophisticated, you can break the functionality into multiple files to make it more reusable and maintainable.
 
For more information on this topic, check out the following resources: