Tutorial: Salesforce.com on AIR with Flex 3

This tutorial has been updated to Flex 3 Beta 2. The new version is now on the Adobe Developer Connection:
Building a standalone Adobe AIR application on salesforce.com with Flex 3

The excitement around using Flex & AIR to build amazing front-ends for Salesforce applications continues to grow. Nitobi has posted a cool AIR application that uses the Salesforce Ajax library. Also Dave Carroll of Salesforce has posted a great blog about why Flex & AIR developers should care about the Apex platform. Back in April I posted the first version of a tutorial about how to use the Flex Toolkit for Apex to build AIR (was Apollo) applications. Since the Flex 3 and AIR betas were released recently it’s time to update that tutorial. So if you want to start building some sexy interfaces on top of salesforce.com follow along…

1. Download and unzip the Flex Toolkit for Apex:
http://wiki.apexdevnet.com/index.php/Flex_Toolkit

2. Download and install the Flex 3 Beta:
http://labs.adobe.com/technologies/flex/flexbuilder3/

3. Create a new AIR Project:

4. Add the Salesforce SWC to the Library Build Path:

5. Write your AIR application:

<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:salesforce="http://www.salesforce.com/"
  creationComplete="conn.loginWithCredentials('dev@mavericks.demo', '123456', new AsyncResponder(loginResult, loginFault));">

  <mx:Script>
  <![CDATA[
  import mx.controls.Alert;
  import com.salesforce.results.QueryResult;
  import com.salesforce.AsyncResponder;

  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>

6. Save it (which automatically compiles it)

7. Run it:

8. Export it as an installable AIR file so you can share it with others

9. Say “That’s Hot!”

Now go ahead and build some amazing Flex and AIR applications on top of salesforce.com! Just let me know what you create so that I can use it in my demos. :)

Download the AIR file for this tutorial

This entry was posted in Adobe AIR, Flex, Salesforce.com. Bookmark the permalink. Post a comment or leave a trackback: Trackback URL.
  • http://Gettingerror1195onthiscode Brendan

    I cut and paste your code to recreate the app in my own environment but I am running into inaccesible method… any guidance??

  • http://www.jamesward.org James Ward

    Hi Brendan,

    The loginWithCredentials method has been replaced. So now you need to do:
    conn.login(new LoginRequest({username: username, password: passwd, callback: new AsyncResponder(loginResult, loginFault)}));

    Also, make sure you import the com.salesforce.objects.LoginRequest class.

    Let me know if that works.

    -James

  • http://www.simonpalmer.com Simon Palmer

    any idea why I would get an http io error (2032) when I try this from a browser based flex 2 app?

  • http://www.jamesward.org James Ward

    I think there are 2 possible reasons:
    1) The Flex Toolkit for Apex might not be requesting the crossdomain.xml file. If this is the case it is a bug. I’ll look into this.
    2) Salesforce implemented new login security restrictions:
    http://trust.salesforce.com/trust/security/identity_feature.html
    Perhaps your computer has not yet been activated yet? We probably need to see what modifications could be made to the Toolkit to better account for this situation.

    Let me know if that helps.

    -James

  • http://www.simonpalmer.com Simon Palmer

    James,

    thanks for the reply

    for 1) I’m pretty sure the toolkit refers to the crossdomain.xml file, but I can’t figure out how it gets it or what it does with it. There is certainly a call to Security.loadPolicyFile(policyUrl) and the policyUrl variable is set to a URI which I can resolve successfully in a browser and which appears to give pretty open access (https://www.salesforce.com/services/crossdomain.xml). Worryingly there is also a crossdomain file at https://www.salesforce.com/crossdomain.xml which has very restrictive access. I am hoping that will not somehow clash – I have to say I find the crossdomain stuff all a bit of a mystery.
    for 2) I was aware of this and I am an active Salesforce user so I was confronted by this in my normal line of activity and I authorized my machine as requested. I have to say that is a *really* bad solution for Salesforce users, but I suspect my voice is a whisper on the wind. Unless there is something special I have to do for a developer account then I think I have done what I need to do to “activate” my machine.

    Do you kow anyone who is successfully using the toolkit or Salesforce Web Services in Flash? I have to say that I am doubting it actually works. There’s every chance it is the recent security changes they made which are preventing this from working. Who is the right person at Salesforce.com to talk to?

    thanks
    Simon

  • http://www.jamesward.org James Ward

    Hi Simon,

    I’ve personally tested the crossdomain stuff in the Toolkit by uploading a Flex app that uses the toolkit to my server and running it successfully. But that was a little while ago. So it’s possible that something broken with this.

    There are quite a few people who have successfully used the Toolkit to talk from their Flex app (on their own site) to Salesforce. So it certainly should work. So your problem is likely either a new bug in the Toolkit or a problem related to how Salesforce changed their security model. I’ll try with the latest Toolkit to make sure the crossdomain stuff still works. That will narrow down the problem a bit.

    To get help from Salesforce you can post a message on their message board:
    http://community.salesforce.com/rss/board?board.id=general_development

    Ron Hess and Dave Carroll are pretty good about responding to problems that have to do with the Flex Toolkit for Apex.

    -James

  • http://www.simonpalmer.com Simon Palmer

    James,

    thanks again. Ron Hess’ name is in the code so I sent him a message, but received no response – probably because of the holiday season. I also posted on a couple of forums (fora?) at Salesforce.com and again am waiting patiently for any replies.

    I’d really appreciate you re-running your app in light of the Salesforce.com changes. Do you think the crossdomain.xml at their root domain has any influence on the problem?

    Needless to say this is a key piece in my particular puzzle and without it I am going to have to do a major architectural re-think.

    Simon

  • http://www.jamesward.org James Ward

    It looks like there might be a bug in the Toolkit. I’m looking further into this. I’ll get back to you.

    -James

  • http://www.simonpalmer.com Simon Palmer

    If I can be of any help at all, please let me know. You can contact me directly at simon . palmer @ gmail . com

  • http://www.jamesward.org James Ward

    Hi Simon,

    I think we’ve figured it out. Flash Player won’t let an application on a non-https server make requests to another server via https. So you either need to set your protocol to http on your Connection, or put your app on an https server. Make sense? Does it work? Let me know. Thanks.

    -James

  • http://www.simonpalmer.com Simon Palmer

    James,

    Thanks for this. I just figured it out. It’s not the protocols it is the new trust settings that salesforce.com have imposed. I got myself a “security key” from my account on the web site and appended it to my password and now I can log in. This is a really ugly solution but does at least work.

    Just FYI my app is running under JBoss on port 443 via SSL and I am using a secure endpoint in my server configuration to deliver my flash client to the player, so I think I have a secure connection. My URL starts https://. I have disabled non-SSL ports on the server just to make sure. In my flexlib code I am using https://www.salesforce.com/services/Soap/u/11.0. I believe my protocols match and are both https. I think I have done everything I can to make sure I am running on an HTTPS server.

    The login error I reported was obviously the challenge from the salesforce.com server resulting from their new security policy.

    Thanks for your help.

    Simon

  • http://www.jamesward.org James Ward

    I’m glad you figured it out! I’ll talk to the salesforce.com guys and see if there is a better way we can handle that situation.

    -James

  • http://www.simonpalmer.com Simon Palmer

    Thanks for your help with this James, I really appreciate it.

    One last question, what was the reason for making loginWithCredentials private? I don’t mind using the new method, it just seems a little strange to hide the old API, especially as it is called by login().

    Regards
    Simon

  • http://www.jamesward.org James Ward

    Hi Simon,

    I’m not sure why we did that. I’ll bring it up with Ron & Dave.

    -James

  • http://www.salesforce.com/developer Dave Carroll

    Hi Simon,

    The flex toolkit is one of several toolkits that we provide to make our web services APIs more accessible to developers using different technologies. Since we don’t want to re-document the web services for each technology, we try to maintain consistency in the interfaces we expose in the toolkits. For the login method we broke with that philosophy of a consistent interface and decided to correct it.

    At some point in the future we will move this library from toolkit status, which is to say more of a labs project, to “product” status as we have done in the past with our AJAX toolkit.

    At the end of the day, we are still ironing out the interfaces exposed with the library and adding functionality to keep up with web services API changes and, with your and other developers help, finding and fixing bugs.

    Cheers
    Dave

  • Jon

    Hi James,
    Do you think you could offer some advice on this?

    http://community.salesforce.com/sforce/board/message?board.id=ajax_toolkit&thread.id=5114

  • http://www.jamesward.org James Ward

    Hi Jon,

    It seems like an error is being returned from Salesforce. It might help you trouble shoot this if you use a network sniffer or proxy like Charles so that you can see the actual response from SFDC. Flash Player doesn’t support response codes higher than 200. So errors can be hard to diagnose if they are non-200. I think SFDC was working on making is to that for Flex their errors would come back as 200 but with some way to indicate that it was an error. I’m not sure where they are with that.

    -James

  • sartori

    that was ridiculously easy! now to start making some useful apps….

    thanks for the sample quick-start code!

  • Pingback: HamzaED

  • Roy Kemble

    Hi

    Is there any easy way to change the Account Id in the datagrid to the Account Name??

    Thanks

    Roy

    • http://www.jamesward.com James Ward

      Yup! Just change the SOQL query to grab the Account.Name. You can also adjust the columns that display in the DataGrid by explicitly setting them.

      • Roy Kemble

        Hi

        Thanks for replying.

        Originally I thought this was possible and spent ages trying to get the query to work, but then I read something in the documentation that you could not reference another object in a query in this way with Adobe Flex for salesforce.

        The query I tried was::

        SELECT Account.Name,(SELECT Contact.FirstName, Contact.LastName FROM Account.Contacts)
        FROM Account

        I also tried
        SELECT SELECT Contact.FirstName, Contact.LastName (Select Account.Name FROM Contacts.Account) FROM Contacts
        FROM Account

        With no success either.

        When I try and debug this the conversion to an SOQL query fails, and as I said I could not get it to work.

        If you could help me with the syntax it would be greatly appreciated.

        Roy

  • Roy Kemble

    Hi

    I think that this is the correct syntax to use, but when run the application it converst the query as shown and just puts a second field with the Account ID instead of the Dealer Code.

    16:56:59.014 [INFO] com.salesforce.query.QueryConverter convert:: SOQL: [Select Subject, StartDateTime, Objectives__c, EndDateTime, Description, AccountId Account.Dealer_Code__c From Event order by StartDateTime desc] TO SQL: [select Subject, StartDateTime, Objectives__c, EndDateTime, Description, AccountId AccountId from Entity_Event order by StartDateTime desc]

    Hav I set up something wrongly??

    Thanks

    Roy