Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session

[FB4.5 LCDS AIR] No data to AIR apps.

Avatar

Level 2

Hi everybody.

I'm trying out the new Flash Builder 4.5.1 and in particular the mobile section. Love to create a mobile app.

Been using LCDS for a while now to and loving it. Creating RIA's with the LCDS backend connected to a MySQL database works like a charm.

Now I want to enable LCDS for a new mobile project but i'm running on some trouble.

Things to know: LCDS is working 100%, including the MySQL backend. Can create web bases RIA's that works 100% (CRUD actions).

But when I create a mobile project with a LCDS backend there is no data to be displayed. I use a list component to show a single culomn but nothing.I figured out that the problem lies with AIR. When I delete the mobile project and create an AIR desktop application the problems return. It seems that LCDS only works when the created project is web based. When local AIR apps are created, LCDS doesn't return the from the MySQL database.

I monitored the network calls and these are the results:

ServiceRequest: trigger connect; MessageService; trigger connect
(mx.messaging.messages::CommandMessage)
  body=(Object)#0
  clientId=(null)
  correlationId=""
  destination="test2.Customers"
  headers=(Object)#0
  messageId="8B8011E1-3688-4F12-FCB1-B087B1CB9E51"
  operation="trigger connect"
  timeToLive=0
  timestamp=0

Why is LCDS not working in combination with AIR apps?

EDIT

Finaly it spet out an error message. Within the AIR app:

Could not initialize DataService.
Cannot connect to the server to load configuration for destinations: ["test2.Customers"]

Hope that helps..

7 Replies

Avatar

Level 3

The issue is that you are not getting a channel connection between the AIR app and the server. You have to create ChannelSet and Channel explicitly in the script block of your MXML file.

This section of the doc should help as a reference:

http://help.adobe.com/en_US/LiveCycleDataServicesES/3.1/Developing/WS4ba8596dc6a25eff-56f1c8f4126dcd...

Basically, you need something like the bolded text below in your script block. Note that this is for an app build using model-driven development. The bolded items would be essentially the same though; one small difference that you would reference your DataService object with yourService.channelSet rather than productService.serviceControl.channelSet. The "serviceControl" is the name of the DataService instance in a generated service wrapper and applies only to model-driven development.


<?xml version="1.0" encoding="utf-8"?> 
<s:WindowedApplication xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx" xmlns:OfflineAIRAPP="OfflineAIRAPP.*"
preinitialize="app_preinitializeHandler(event)"
creationComplete="windowedapplication1_creationCompleteHandler(event)">
    <fx:Script>
        <![CDATA[
            import com.adobe.offline.ProductOfflineAdapter;
            
            import mx.controls.Alert;
            import mx.events.FlexEvent;
           import mx.messaging.Channel;
            import mx.messaging.ChannelSet;
            import mx.messaging.channels.RTMPChannel;
            import mx.messaging.events.ChannelEvent;

            import mx.rpc.AsyncToken;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
            
            public var myOfflineAdapter:ProductOfflineAdapter;
            public function channelConnectHandler(event:ChannelEvent):void
            {
                productService.serviceControl.autoConnect=false;
                
            }
          protected function 
                app_preinitializeHandler(event:FlexEvent):void
            {
                var cs:ChannelSet = new ChannelSet();
                var customChannel:Channel = new RTMPChannel("my-rtmp",
                    "rtmp://localhost:2037");
                cs.addChannel(customChannel);
                productService.serviceControl.channelSet=cs;
                customChannel.addEventListener(ChannelEvent.CONNECT,
                    channelConnectHandler);
           
}

            
            protected function dataGrid_creationCompleteHandler(event:FlexEvent):void
            {
                getAllResult.token = productService.getAll();
            }
            
            protected function
                windowedapplication1_creationCompleteHandler(event:FlexEvent):void
            {
                productService.serviceControl.autoCommit = false;
                productService.serviceControl.autoConnect = false;
                productService.serviceControl.autoSaveCache = false;
                productService.serviceControl.offlineAdapter = new
                    ProductOfflineAdapter();
                productService.serviceControl.fallBackToLocalFill=true;
                productService.serviceControl.encryptLocalCache = true;
                productService.serviceControl.cacheID = "myOfflineCache";
            }
            
            protected function connectBtn_clickHandler(event:MouseEvent):void
            {
                productService.serviceControl.connect();
            }
            
            protected function DisconnectBtn_clickHandler(event:MouseEvent):void
            {
                productService.serviceControl.disconnect();
            }
            
            protected function commitBtn_clickHandler(event:MouseEvent):void
            {
                productService.serviceControl.commit();
            }
            
            protected function saveCacheBtn_clickHandler(event:MouseEvent):void
            {
                productService.serviceControl.saveCache();
            }
            
        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:CallResponder id="getAllResult" />
        <OfflineAIRAPP:ProductService id="productService"
            fault="Alert.show(event.fault.faultString + '\n' +
            event.fault.faultDetail)"/>
    </fx:Declarations>
    <mx:DataGrid editable="true" x="9" y="10" id="dataGrid"
        creationComplete="dataGrid_creationCompleteHandler(event)"
        dataProvider="{getAllResult.lastResult}">
        <mx:columns>
            <mx:DataGridColumn headerText="productid" dataField="productid"/>
            <mx:DataGridColumn headerText="description" dataField="description"/>
            <mx:DataGridColumn headerText="price" dataField="price"/>
            <mx:DataGridColumn headerText="productname" dataField="productname"/>
        </mx:columns>
    </mx:DataGrid>
    <s:Button x="10" y="246" label="Connect" click="connectBtn_clickHandler(event)"
        id="connectBtn" width="84" height="30"/>
    <s:Button x="112" y="204" label="Save to Local Cache" id="saveCacheBtn"
        click="saveCacheBtn_clickHandler(event)" height="30"/>
    <s:Button x="110" y="246" label="Commit to Server" id="commitBtn"
        click="commitBtn_clickHandler(event)" width="135" height="30"/>
    <s:Button x="10" y="204" label="Disconnect" id="DisconnectBtn"
        click="DisconnectBtn_clickHandler(event)" height="30"/>
    <s:Label x="270" y="204" text="{'Commit Required: ' +
        productService.serviceControl.commitRequired}"/>
    <s:Label x="270" y="246" text="{'Connected: ' +
        productService.serviceControl.connected}"/>
</s:WindowedApplication>

Avatar

Level 2

Thank you so much for your answer! Really apreseate it!

It helped me a long way and i'm now capable of creating LCDS driven AIR apps.

Only problem though with the Mobile section. Did everything by the book but the list is still not getting populated.. The code:

<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
               xmlns:s="library://ns.adobe.com/flex/spark"
               xmlns:test7="test7.*"
               preinitialize="app_preinitializeHandler(event)"
               creationComplete="windowedapplication1_creationCompleteHandler(event)"
               applicationDPI="160">
    <fx:Script>
        <![CDATA[
           
            import com.adobe.offline.ProductOfflineAdapter;
           
            import mx.events.FlexEvent;
            import mx.messaging.Channel;
            import mx.messaging.ChannelSet;
            import mx.messaging.channels.RTMPChannel;
            import mx.messaging.events.ChannelEvent;
            import mx.rpc.AsyncToken;
            import mx.rpc.events.FaultEvent;
            import mx.rpc.events.ResultEvent;
           
            public var myOfflineAdapter:ProductOfflineAdapter;
            public function channelConnectHandler(event:ChannelEvent):void
            {
                productService.serviceControl.autoConnect=false;
               
            }
            protected function 
                app_preinitializeHandler(event:FlexEvent):void
            {
                var cs:ChannelSet = new ChannelSet();
                var customChannel:Channel = new RTMPChannel("my-rtmp",
                    "rtmp://localhost:2037");
                cs.addChannel(customChannel);
                productService.serviceControl.channelSet=cs;
                customChannel.addEventListener(ChannelEvent.CONNECT,
                    channelConnectHandler);
            }
           
            protected function dataGrid_creationCompleteHandler(event:FlexEvent):void
            {
                getAllResult.token = productService.getAll();
            }
           
            protected function
                windowedapplication1_creationCompleteHandler(event:FlexEvent):void
            {
                productService.serviceControl.autoCommit = false;
                productService.serviceControl.autoConnect = false;
                productService.serviceControl.autoSaveCache = false;
                productService.serviceControl.offlineAdapter = new
                    ProductOfflineAdapter();
                productService.serviceControl.fallBackToLocalFill=true;
                productService.serviceControl.encryptLocalCache = true;
                productService.serviceControl.cacheID = "myOfflineCache";
            }
           
            protected function list_creationCompleteHandler(event:FlexEvent):void
            {
                getAllResult.token = productService.getAll();
            }
           
        ]]>
    </fx:Script>
    <fx:Declarations>
        <s:CallResponder id="getAllResult"/>
        <test7:ProductService id="productService"/>
        <!-- Place non-visual elements (e.g., services, value objects) here -->
    </fx:Declarations>
    <s:List id="list" x="10" y="10" creationComplete="list_creationCompleteHandler(event)"
            labelField="productname">
        <s:AsyncListView list="{getAllResult.lastResult}"/>
    </s:List>
</s:Application>

It is just a simple list component that needs to be filled, in this case by the LCDS sample database. When I monitor the network connections, the trigger is running succesfully with the following output:

ServiceRequest: trigger connect; MessageService; trigger connect
(mx.messaging.messages::CommandMessage)
  body=(Object)#0
  clientId=(null)
  correlationId=""
  destination="test7.Product"
  headers=(Object)#0
  messageId="28C54E63-357A-6ACF-B9FD-C0889B6115E9"

Status: OK

But there is no Fill execution. When I run this code in an AIR desktop application all runs smooth. Air starts -> connection trigger OK -> Fill execution OK -> And i have a lovely list component filled with Data. When I run this in a mobile app the connection trigger is OK but the fill is not executed.

Can you help? If you need any further information, just let me know!

thx!

Avatar

Level 2

You are using "rtmp://localhost:2037" as your channel URL. You need to use the real IP or servername since localhost is unknown to a mobile.

Regards,

KenS

Avatar

Level 2

It doenn't really matter of I change the Localhost to an external adres like an IP or server adres, it sas that it has a connection to the server. The Fill doesn't get executed and I don't know why.

Changed the localhost adres to a staic IP from the server though, thx for the advice!

Please, anyone have a clue why the Fill is not working? I'm reallt stuck here..

Avatar

Level 2

I have tried duplicating your issue. When I use your code and create a new model against Product - both the air desktop and mobile project work for me. Send me your project in a private message and I will take a look at it (as time allows).

,

Avatar

Level 2

Thank you very much for the effort! I'm currenly at work. When I get home i'll

get right on it.

And again, thx!