After my first hello world post using Adobe Flash Builder
4.5.1, I wanted to push a little bit further and try to create a small mobile
app that interacts with Magento. If you don’t have Flash Builder 4.5.1, you can
get a trial from Adobe at http://www.adobe.com/products/flashbuilder/
Magento is rapid growing open source platform for ecommerce,
if you don't have it, you can get the community version from http://www.magentocommerce.com/download.
Installing Magento could it be a little bit tricky, but there is plenty of
information in the web. I've found that the best solution for this kind of POC
is to have a virtual machine (virtual box) running Ubuntu desktop and have
Magento running on that machine. It will also necessary to have the Sample data
installed. Here is a link to start http://www.amicontech.com/blog/setting-up-magento-on-ubuntu/
Accessing the API
Once you have Magento up and running, you will need to set
up a user with grants to access the API:
http://www.magentocommerce.com/boards/viewthread/23208/
Goto: System ->
Web Services -> Roles and define a Role set for your API user with the
allowed actions.
For testing purposes you may create a temporary “can do
everything” role first, and if things work nice, change that role to be as
restrictive as necessary.
Save that Role and head over to: System > Web Services
> Users
Add a new User, the username is your “api user”, and the key
(~ password) is the “api key”
Assign a Role in the second tab and Save.
Create a Flex Mobile Project
Open Flash builder and create a Flex Mobile Project by choosing
File -> New -> Flex Mobile Project. This will open the wizard, which we will
use to create the project.
On the Project Location screen, we are going to set up the
project name (MagentoMobilePOC), location and Flex SDK.
On the Mobile Settings screen, we are going to select
settings specific to the target platform, for now, just select "Apple
iOS" and "View Based Application" as a template
On the Server Settings screen, we are going to select NONE
as the application server type; we are going to add the service reference
latter on.
On the Build paths screen, we are going to set the
application ID. This ID should be unique, reverse domain naming convention
works like a charm!
The web service's client
On the Data / Services tab, click on the link "Connect
to Data/Service...". On the next page, select Web Service (WSDL) and add
the magento api url on the next page: http://your_magento_host/magento/api/v2_soap?wsdl=1
(where your_magento_host is the url where your local copy of magento is
running), change the service name to "magento" (without the quotes)
and the Data type package to "model" (again, without the quotes) and
click on next.
From the operations to import, unselect all and select just
the following and click on Finish
- login(username:String, apiKey:string):string
- customerCustomerList(sessionId:string,
filters:Filters):customerCustomerEntityArray
- customerCustomerCreate(sessionId:string, customerData:custoemrCustomerEntityToCreate):int
Flash builder will create the required classes with the code
to interact with Magento.
Login View
This is not going to be a part of an actual application, but
it will let us enter different combinations of user and password to test.
Open the MagentoMobilePOCHomeView.mxml file, and add a
couple of text boxes, a button and a label with the following id: txtUsername,
txtPassword, btnLogin and lblMessage.

Select the btnLogin and select "Generate Event
Handler" from the On click event, it will add the method stub to handle
the click event
From the Data/Services tab, right click on the login web
method, and click on "Generate Service Call", it will add the code to
call the login web method.
Web service calls on Adobe Air are asynchronous, so we need
to setup a kind of “callback” function to handle the result (and the fault), let’s
add these two pieces of code. Modify the following line:
<s:CallResponder id="loginResult"/>
Write “result” (without the quotes) before the backslash,
the IDE should give you the option to create the result event handler if you
double click on, click on “Generate Event Handler”, it will add a stub method
to handle the service call result. Do the same for the fault event handler. If
the IDE is not giving you the option, try again or add the code by hand… the
IDE it’s not quite consistent and I really hope they improve it a lot. Being
used to work in MS Visual Studio 2008 / 2010 I took this little things for
granted and is somehow frustrating to not have the same response from the IDE
doing the same things
Customer List View
Let’s add a new View to show the customer List, right click
on the “view” package and add a new MXML Component with CustomerListView as
name. Add a label (lblMessage) a List (lstCustomer) and three buttons (btnBack,
btnAdd, btnRefresh). Add an event handler for each of the button click events.
Also, generate the service call for the customerCustomerList web method.

Add the following code to the <fx:Declarations>
section
<s:ArrayCollection id="customers">
</s:ArrayCollection>
We are going to use it to contain the list of customers we
are going to receive from the web method.
Also, modify the List declaration adding these two
parameters to bind the list with the customer array collection:
dataProvider="{customers}"
labelField="email"
Generate the service call for the customerCustomerList web
method and add the event handlers for the result and fault.
Customer Details View
Let’s add a new View to add a customer with CustomerDetailView
as a name. Add a label (lblMessage), four text inputs (txtLastName,
txtFirstName, txtEmail and txtPassword) and two buttons (btnBack and btnSave),
you can also set the “prompt” property
of each text input to give the user a hint of what the application is expecting
to receive on those fields. For the password text box, there is a “displayAsPasword”
property that will hide the characters. We are not going to go into validation
in this example.
Generate the service call for the customerCustomerCreate web
method and add the event handlers for the result and fault.

Navigation
The application flow should be, from the home view, once the
user sets the username, password and tap on the login button; we should go to
the CustomerListView and list the magento customers. If the user clicks on Add,
we should go to the CustomerDetailView, on this view, if the user taps on back
or successfully save the new customer, we go back to the CustomerListView. From
here, we can go back to the home view or add a new customer. Let’s add the code
to make the navigation happen.
On the home view, go to the btnLogin_clickHandlerevent
handler and add the following code, while you are at it, take a look at the
optional second parameter (data)… we are going to use it later ;)
navigator.pushView(CustomerListView);
On the CustomerListView, go to the btnBack_clickHandler and
add the following code:
navigator.popView();
On the same view, go to the btnAdd_clickHandler and add the
following code:
navigator.pushView(CustomerDetailView);
On the CustomerDetailView, go to the btnSave_clickHandler and add the following
code:
navigator.popView();
Do same for the btnBack_clickHandler handler.
Try it on the emulator, you will be able to go back and
forth from each one of the application views, starting from the login.
Hi Magento, my name is Adobe Air, nice to meet you.
We have the UI and the navigation implemented, let see if we
can talk “magento” ;)
On the HomeView: go
to the btnLogin_clickHandler and replace the navigation code with the following
navigator.pushView(CustomerListView);
Next, go to the loginResult_faultHandler and add the
following, we are going to show whatever error we may get from magento on the
lblMessage
lblMessage.text = event.fault.faultString;
Next, go to the loginResult_resultHandler and add the
following:
navigator.pushView(CustomerListView,
event.result.toString());
What are we doing here is to push the new view on the
navigator and passing the result of the login (a retrieved from magento SessionId)
Here is the full code of the HomeView:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:magento="services.magento.*"
title="Customer Detail"
add="customerDetailView_addHandler(event)">
<fx:Script>
<![CDATA[
import model.CustomerCustomerEntityToCreate;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected var sessionId:String;
protected function customerCustomerCreate(sessionId:String, customerData:CustomerCustomerEntityToCreate):void{
customerCustomerCreateResult.token = magento.customerCustomerCreate(sessionId, customerData);
}
protected function customerCustomerCreateResult_resultHandler(event:ResultEvent):void{
navigator.popView();
}
protected function customerCustomerCreateResult_faultHandler(event:FaultEvent):void{
lblMessage.text = event.fault.faultString;
}
protected function btnSave_clickHandler(event:MouseEvent):void{
var customerData:CustomerCustomerEntityToCreate = new CustomerCustomerEntityToCreate();
customerData.lastname = txtLastName.text;
customerData.firstname = txtFirstName.text;
customerData.email = txtEmail.text;
customerData.password = txtPassword.text;
customerCustomerCreate(sessionId, customerData)
}
protected function btnBack_clickHandler(event:MouseEvent):void{
navigator.popView();
}
protected function customerDetailView_addHandler(event:FlexEvent):void{
sessionId = data.toString();
}
]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="customerCustomerCreateResult" result="customerCustomerCreateResult_resultHandler(event)" fault="customerCustomerCreateResult_faultHandler(event)"/>
<magento:Magento id="magento"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:navigationContent>
<s:Button id="btnBack" label="Back" click="btnBack_clickHandler(event)"/>
</s:navigationContent>
<s:actionContent>
<s:Button id="btnSave" label="OK" click="btnSave_clickHandler(event)"/>
</s:actionContent>
<s:TextInput id="txtLastName" x="22" y="40" prompt="Last Name"/>
<s:TextInput id="txtFirstName" x="22" y="114" prompt="First Name"/>
<s:TextInput id="txtEmail" x="22" y="188" prompt="Email"/>
<s:TextInput id="txtPassword" x="22" y="262" displayAsPassword="true" prompt="Password"/>
<s:Label id="lblMessage" x="18" y="10" width="612" text="Label"/>
</s:View>
Let’s add the handler on the CustomerListView to manage the “add”
event and take note of the session ID retrieved on the login, since we are
going to need for any further call to magento.
Open the CustomerListView, on the definition node <s:View…>
add a handler for the “add” event as we did for the result and fault for the services.
Cross your fingers and hope the IDE helps you ;)
Change the orginal name (view1_addHandler) for something
more useful (customerListView_addHandler) . To do that, select the whole
handler name and press Ctrl + Alt + R, a dialog box asking for the new name
will appear, once you click on Ok, all references to the old name will be
replaced with the new oneJ,
replace the event handler code with the following (we are declaring a string
variable to hold the session id and also calling the customer list web method)
protected var sessionId : String;
protected function
customerListView_addHandler(event:FlexEvent):void
{
sessionId
= data.toString();
}
Here is the rest of the code, binding the customer result
and showing the error message if any:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"xmlns:s="library://ns.adobe.com/flex/spark"xmlns:magento="services.magento.*"title="Customers List" add="customerListView_addHandler(event)" >
<fx:Script>
<![CDATA[
import model.Filters;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected var sessionId : String;
protected function btnBack_clickHandler(event:MouseEvent):void{
navigator.popView();
}
protected function btnAdd_clickHandler(event:MouseEvent):void{
navigator.pushView(CustomerDetailView, sessionId);
}
protected function btnRefresh_clickHandler(event:MouseEvent):void{
customerCustomerList(sessionId, new Filters());
}
protected function customerCustomerList(sessionId:String, filters:Filters):void{
customerCustomerListResult.token = magento.customerCustomerList(sessionId, filters);
}
protected function customerCustomerListResult_resultHandler(event:ResultEvent):void{
var result:ArrayCollection = event.result as ArrayCollection;
customers = result;
}
protected function customerCustomerListResult_faultHandler(event:FaultEvent):void{
lblMessage.text = event.fault.faultString;
}
protected function customerListView_addHandler(event:FlexEvent):void{
sessionId = data.toString();
customerCustomerList(sessionId, new Filters());
}
]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="customerCustomerListResult" result="customerCustomerListResult_resultHandler(event)" fault="customerCustomerListResult_faultHandler(event)"/>
<magento:Magento id="magento"/>
<s:ArrayCollection id="customers"></s:ArrayCollection>
<s:CallResponder id="customerCustomerListResult2"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:navigationContent>
<s:Button id="btnBack" label="Back" click="btnBack_clickHandler(event)"/>
</s:navigationContent>
<s:actionContent>
<s:Button id="btnAdd" label="Add" click="btnAdd_clickHandler(event)"/>
</s:actionContent>
<s:Label id="lblMessage" x="10" y="10" width="620" text="Label"/>
<s:List id="lstCustomer" x="10" y="48" width="620" height="579" dataProvider="{customers}" labelField="email" ></s:List>
<s:Button id="btnRefresh" x="470" y="635" label="Refresh" click="btnRefresh_clickHandler(event)"/>
</s:View>
Adding a new Customer, here is the code for the
CustomerDetailView:
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"xmlns:s="library://ns.adobe.com/flex/spark"xmlns:magento="services.magento.*"title="Customer Detail" add="customerDetailView_addHandler(event)">
<fx:Script>
<![CDATA[
import model.CustomerCustomerEntityToCreate;
import mx.events.FlexEvent;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
protected var sessionId:String;
protected function customerCustomerCreate(sessionId:String, customerData:CustomerCustomerEntityToCreate):void{
customerCustomerCreateResult.token = magento.customerCustomerCreate(sessionId, customerData);
}
protected function customerCustomerCreateResult_resultHandler(event:ResultEvent):void{
navigator.popView();
}
protected function customerCustomerCreateResult_faultHandler(event:FaultEvent):void{
lblMessage.text = event.fault.faultString;
}
protected function btnSave_clickHandler(event:MouseEvent):void{
var customerData:CustomerCustomerEntityToCreate = new CustomerCustomerEntityToCreate();
customerData.lastname = txtLastName.text;
customerData.firstname = txtFirstName.text;
customerData.email = txtEmail.text;
customerData.password = txtPassword.text;
customerCustomerCreate(sessionId, customerData)
}
protected function btnBack_clickHandler(event:MouseEvent):void{
navigator.popView();
}
protected function customerDetailView_addHandler(event:FlexEvent):void{
sessionId = data.toString();
}
]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="customerCustomerCreateResult" result="customerCustomerCreateResult_resultHandler(event)" fault="customerCustomerCreateResult_faultHandler(event)"/>
<magento:Magento id="magento"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:navigationContent>
<s:Button id="btnBack" label="Back" click="btnBack_clickHandler(event)"/>
</s:navigationContent>
<s:actionContent>
<s:Button id="btnSave" label="OK" click="btnSave_clickHandler(event)"/>
</s:actionContent>
<s:TextInput id="txtLastName" x="22" y="40" prompt="Last Name"/>
<s:TextInput id="txtFirstName" x="22" y="114" prompt="First Name"/>
<s:TextInput id="txtEmail" x="22" y="188" prompt="Email"/>
<s:TextInput id="txtPassword" x="22" y="262" displayAsPassword="true" prompt="Password"/>
<s:Label id="lblMessage" x="18" y="10" width="612" text="Label"/>
</s:View>
Try it, I had a couple of customers added to my local
magento, you can check it by accessing the admin section of magento an going to
Customers
Hope it helps you making your mobile applications to talk
with Magento =)
Add comment