How to use Esri Flex API on Android and iPhone
Update (Jun 2011) : For more updated info, check out my ADC article here.
At MAX2010 (Awesome BTW) Adobe introduced Flex SDK Hero and Flash Builder Burrito which enables you to build and deploy Flex mobile applications on Android by default. In addition, using the revitalized Packager for iPhone, you can postprocess the swf into an ipa that you can deploy on an iPhone using iTunes.
In this post, I will share with you the steps that I took to use the Flex API for ArcGIS to build a mobile mapping application.
First and foremost - RTFM - here are some links that u _need_ to read specially for iPhone provisioning:
http://opensource.adobe.com/wiki/display/flexsdk/Hero
http://labs.adobe.com/technologies/flashbuilder_burrito/
http://labs.adobe.com/technologies/packagerforiphone/
The cool part of this whole process is now you have one code base to build upon and deploy on Android and iPhone and in the future whatever mobile platform Adobe decides to support.
You can download the source code of the sample application from here.
This simple application queries the states demographic layer in arcgis.com and displays the result as a list. By taking advantage of the new state syntax in Flex 4, if the user rotates the phone to view the info in landscape mode, the list is replaced with a map showing the selected states. Cool ?
There is no new Flex API for ArcGIS to learn. I'm using the same old Query, QueryTask, Map, ArcGISTiledLayer, GraphicLayer and SimpleFillSymbol classes from the released Flex API.
Now, to compile the application using Flash Builder Burrito, make sure to include in the libs project folder the flexapi swc and make sure to copy from the Flex sdks folder (under the burrito application folder) the mx.swc and the sparkskins.swc files. For the next release of our swc will not require the last two swc, just add them for now. Your package explorer in Flash Builder should look like this:

Now you can compile, deploy and run your swf on the USB attached Android. Make sure that you have the latest AIR runtime on your phone. If not, then delete AIR using the Settings view and redeploy the application, the latest runtime engine will be automagically installed.
Now to the iPhone. Currently, Burrito does not have a built-in wizard to postprocess the swf into and an ipa. This must be done via command line tools. So, download and install the latest iphone packager for your platform (windows or mac). In my case, I had to re-compile the source code to reproduce the swf. Here is the content of my bash shell script:
Next is to convert the swf to an ipa. Here is the content of my shell script:
Here is the content of MyMobileApp-ios.xml:
Again - if you want to know what all the above options mean - you _must_ read the packager documentation. The pfi command will run for a long time - do not worry - it will eventually finish - again, this is still in its early stages, and I hope that Adobe will make this easier and faster in the future.
Now drag the ipa file onto iTunes and sync your iPhone. you should in theory have the app on your iPhone.
I hope this works for you and tell me what you think.
At MAX2010 (Awesome BTW) Adobe introduced Flex SDK Hero and Flash Builder Burrito which enables you to build and deploy Flex mobile applications on Android by default. In addition, using the revitalized Packager for iPhone, you can postprocess the swf into an ipa that you can deploy on an iPhone using iTunes.
In this post, I will share with you the steps that I took to use the Flex API for ArcGIS to build a mobile mapping application.
First and foremost - RTFM - here are some links that u _need_ to read specially for iPhone provisioning:
http://opensource.adobe.com/wiki/display/flexsdk/Hero
http://labs.adobe.com/technologies/flashbuilder_burrito/
http://labs.adobe.com/technologies/packagerforiphone/
The cool part of this whole process is now you have one code base to build upon and deploy on Android and iPhone and in the future whatever mobile platform Adobe decides to support.
You can download the source code of the sample application from here.
This simple application queries the states demographic layer in arcgis.com and displays the result as a list. By taking advantage of the new state syntax in Flex 4, if the user rotates the phone to view the info in landscape mode, the list is replaced with a map showing the selected states. Cool ?
There is no new Flex API for ArcGIS to learn. I'm using the same old Query, QueryTask, Map, ArcGISTiledLayer, GraphicLayer and SimpleFillSymbol classes from the released Flex API.
Now, to compile the application using Flash Builder Burrito, make sure to include in the libs project folder the flexapi swc and make sure to copy from the Flex sdks folder (under the burrito application folder) the mx.swc and the sparkskins.swc files. For the next release of our swc will not require the last two swc, just add them for now. Your package explorer in Flash Builder should look like this:

Now you can compile, deploy and run your swf on the USB attached Android. Make sure that you have the latest AIR runtime on your phone. If not, then delete AIR using the Settings view and redeploy the application, the latest runtime engine will be automagically installed.
Now to the iPhone. Currently, Burrito does not have a built-in wizard to postprocess the swf into and an ipa. This must be done via command line tools. So, download and install the latest iphone packager for your platform (windows or mac). In my case, I had to re-compile the source code to reproduce the swf. Here is the content of my bash shell script:
FLEX_HOME="/Applications/Adobe Flash Builder Burrito/sdks/4.5.0"
"${FLEX_HOME}/bin/mxmlc"\
-load-config "${FLEX_HOME}/frameworks/airmobile-config.xml"\
-compiler.include-libraries+=libs\
-sp src\
-o bin-debug/MyMobileApp.swf src/MyMobileApp.mxml
Next is to convert the swf to an ipa. Here is the content of my shell script:
~/packagerforiphone_v2_mac_101110/bin/pfi\
-package\
-target ipa-test\
-provisioning-profile ~/YourProfile.mobileprovision\
-storetype pkcs12\
-keystore ~/YourFile.p12\
-storepass YourPassword\
MyMobileApp.ipa\
bin-debug/MyMobileApp-ios.xml\
bin-debug/MyMobileApp.swf\
bin-debug/assets/Default.png\
bin-debug/assets/Icon29.png\
bin-debug/assets/Icon57.png\
bin-debug/assets/Icon512.png
Here is the content of MyMobileApp-ios.xml:
<?xml version="1.0" encoding="UTF-8"?>
<application xmlns="http://ns.adobe.com/air/application/2.0">
<id>ThunderHead</id>
<filename>MyMobileApp</filename>
<name>MyMobileApp</name>
<version>v1</version>
<initialWindow>
<renderMode>gpu</renderMode>
<content>bin-debug/MyMobileApp.swf</content>
<fullScreen>true</fullScreen>
<aspectRatio>portrait</aspectRatio>
<autoOrients>true</autoOrients>
</initialWindow>
<supportedProfiles>mobileDevice</supportedProfiles>
<icon>
<image29x29>bin-debug/assets/Icon29.png</image29x29>
<image57x57>bin-debug/assets/Icon57.png</image57x57>
<image512x512>bin-debug/assets/Icon512.png</image512x512>
</icon>
<iPhone>
<InfoAdditions><![CDATA[
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleBlackOpaque</string>
<key>UIRequiresPersistentWiFi</key>
<string>NO</string>
]]></InfoAdditions>
</iPhone>
</application>
Again - if you want to know what all the above options mean - you _must_ read the packager documentation. The pfi command will run for a long time - do not worry - it will eventually finish - again, this is still in its early stages, and I hope that Adobe will make this easier and faster in the future.
Now drag the ipa file onto iTunes and sync your iPhone. you should in theory have the app on your iPhone.
I hope this works for you and tell me what you think.
Comments
Any chance you can post more detail on the process of porting to ipa? All the doc assumes using Flash CS5, but i am using Flash Builder "Burrito" - assume that is OK?
Other then that, it does run, albeit slow.
GREAT Job and I do see what is possible, and I believe Adobe will definitely improve this one.
i'm getting this error when packing...
Exception in thread "main" java.lang.Error: Unable to find named traits: mx.collections.errors::SortError
at adobe.abc.Domain.resolveTypeName(Domain.java:195)
at adobe.abc.Domain.resolveTypeName(Domain.java:112)
at adobe.abc.GlobalOptimizer$InputAbc.resolveTypeName(GlobalOptimizer.java:274)
at adobe.abc.GlobalOptimizer$InputAbc.readCode(GlobalOptimizer.java:983)
at adobe.abc.GlobalOptimizer$InputAbc.readBody(GlobalOptimizer.java:531)
at adobe.abc.GlobalOptimizer$InputAbc.readAbc(GlobalOptimizer.java:404)
at adobe.abc.GlobalOptimizer$InputAbc.readAbc(GlobalOptimizer.java:280)
at adobe.abc.LLVMEmitter.generateBitcode(LLVMEmitter.java:160)
at com.adobe.air.ipa.AOTCompiler.convertAbcToLlvmBitcode(AOTCompiler.java:329)
at com.adobe.air.ipa.AOTCompiler.GenerateMacBinary(AOTCompiler.java:600)
at com.adobe.air.ipa.IPAOutputStream.compileRootSwf(IPAOutputStream.java:196)
at com.adobe.air.ipa.IPAOutputStream.finalizeSig(IPAOutputStream.java:366)
at com.adobe.air.ADTPackager.createPackage(ADTPackager.java:65)
at com.adobe.air.ipa.IPAPackager.createPackage(IPAPackager.java:165)
at com.adobe.air.ADTEntrypoint.parseArgsAndGo(ADTEntrypoint.java:132)
at com.adobe.air.ipa.PFI.parseArgsAndGo(PFI.java:152)
at com.adobe.air.ADTEntrypoint.run(ADTEntrypoint.java:68)
at com.adobe.air.ipa.PFI.main(PFI.java:112)
any hints?
can you post some images?
"c:\Program Files\Adobe\Adobe Flash Builder Burrito\sdks\4.5.0\bin\mxmlc" -load-config "c:\Program Files\Adobe\Adobe Flash Builder Burrito\sdks\4.5.0\frameworks\airmobile-config.xml" -library-path -sp -o MyMobileApp.swf "c:\Users\Morgan\Adobe Flash Builder Burrito Preview\MyMobileApp\src\MyMobileApp.mxml"
I get an error saying "Error: Could not resolve to a component implement" or an error regarding compile time constants. This sounds like my libraries are not being included in the build. I would greatly appreciate any feedback anyone may have regarding this issue. And yes, i am new to mxmlc compiling, so please forgive me if the answer is obvious. Thanks again,
Morgan
GeoSurf, Inc
VerifyError: Error #1014: Class mx.controls.sliderClasses::Slider could not be found.
at com.esri.ags::Map()[C:\checkout\flex_api2\api\src\com\esri\ags\Map.as:526]
at views::FeatureList/_FeatureList_Map1_i()
at mx.core::DeferredInstanceFromFunction/getInstance()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\DeferredInstanceFromFunction.as:105]
at mx.states::AddItems/createInstance()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\states\AddItems.as:487]
at mx.states::AddItems/initialize()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\states\AddItems.as:502]
at mx.states::State/http://www.adobe.com/2006/flex/mx/internal::initialize()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\states\State.as:257]
at mx.core::UIComponent/initializeState()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\UIComponent.as:10608]
at mx.core::UIComponent/commitCurrentState()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\UIComponent.as:10306]
at mx.core::UIComponent/commitProperties()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\UIComponent.as:8180]
at spark.components.supportClasses::GroupBase/commitProperties()[E:\dev\hero_private_beta\frameworks\projects\spark\src\spark\components\supportClasses\GroupBase.as:1089]
at spark.components::Group/commitProperties()[E:\dev\hero_private_beta\frameworks\projects\spark\src\spark\components\Group.as:826]
at mx.core::UIComponent/validateProperties()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\UIComponent.as:8095]
at spark.components::ViewNavigator/createViewInstance()[E:\dev\hero_private_beta\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1738]
at spark.components::ViewNavigator/commitViewChange()[E:\dev\hero_private_beta\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1661]
at spark.components::ViewNavigator/commitProperties()[E:\dev\hero_private_beta\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1063]
at mx.core::UIComponent/validateProperties()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\UIComponent.as:8095]
at mx.managers::LayoutManager/validateClient()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\managers\LayoutManager.as:934]
at mx.core::UIComponent/validateNow()[E:\dev\hero_private_beta\frameworks\projects\framework\src\mx\core\UIComponent.as:7953]
at spark.components::ViewNavigator/executeDelayedActions()[E:\dev\hero_private_beta\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1170]
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at views::FeatureList/set data()[C:\Users\anash\Adobe Flash Builder 4.5\VernonGIS_Mobile\VernonGIS\src\views\FeatureList.mxml:17]
at spark.components::ViewNavigator/createViewInstance()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1928]
at spark.components::ViewNavigator/commitNavigatorAction()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1849]
at spark.components::ViewNavigator/commitProperties()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1220]
at mx.core::UIComponent/validateProperties()[E:\dev\hero_private\frameworks\projects\framework\src\mx\core\UIComponent.as:8209]
at mx.managers::LayoutManager/validateProperties()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:597]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:813]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1180]
I added in the two swc files that are missing. Any help would be appreciated. I have been trying to resolve this for a week now
Trying to implement this using the 4.5 release and keep getting this error. I have sorted out that it fails when trying to bind dataprovider to the list in this line of code:
list.dataProvider = new ArrayList(featureSet.attributes);
I can see the objects in debug mode, but it doesn't want to bind the attributes for some reason.
Any ideas?
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at views::FeatureList/set data()[/Users/-----/Documents/Adobe Flash Builder 4.5/TestMobile/src/views/FeatureList.mxml:30]
at spark.components::ViewNavigator/createViewInstance()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1928]
at spark.components::ViewNavigator/commitNavigatorAction()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1849]
at spark.components::ViewNavigator/commitProperties()[E:\dev\hero_private\frameworks\projects\mobilecomponents\src\spark\components\ViewNavigator.as:1220]
at mx.core::UIComponent/validateProperties()[E:\dev\hero_private\frameworks\projects\framework\src\mx\core\UIComponent.as:8209]
at mx.managers::LayoutManager/validateProperties()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:597]
at mx.managers::LayoutManager/doPhasedInstantiation()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:813]
at mx.managers::LayoutManager/doPhasedInstantiationCallback()[E:\dev\hero_private\frameworks\projects\framework\src\mx\managers\LayoutManager.as:1180]
Do you find that performance is shot by the adobe framework?
Why does my 4mb (200 lines of code) swf turn into a 23 mb app? (with esri flex, mx and sparkskins swc's)
from here
Although I did *not* have to set my destructionPolicy='never'.
FWIW... I just had to manually set:
data.text = whereInput.text;
right before pushing the QueryResultView. Then when I use navigator.popView() to go back, my last search string is there. I also moved the BusyIndicator into the QueryView and toggle it's visibility with executing/handling the query/response.
thanks for the hack! I have a question though.
Esri docs at http://resources.arcgis.com/en/help/flex-viewer/concepts/index.html#/FAQs/01m300000004000000/ state that:
===================
Is it possible to run the ArcGIS Viewer for Flex application on my iPhone or iPad?
No. There are two specific issues related to this.
The ArcGIS Viewer for Flex is a standard Flex project, it would need to be re-written as a Flex Mobile Project.
The ArcGIS Viewer for Flex uses Flex modules. These are not supported in Flex mobile projects.
===================
What's up with that, is it true that to use Esri Flex on iOS, one needs to ditch the viewer?