Mar 8, 2011
It’s 3am. You have a sexy Flex mobile project that takes full advantage of the Hero SDK and its Spark mobile components. You’re dying to deploy to iPhone and iPad but unfortunately, you either have to build your app using Adobe’s iPhone packager via the command line interface (CLI), wait until Flash Builder includes a GUI that supports this scenario, switch to another IDE (FDT, etc) or re-factor the app from Flex to Flash for compilation via Flash CS5. Nothing’s particularly appealing.
Enter: ANT to the rescue!
By creating an ANT build script, you can alleviate all of the above concerns and stay super-flexible at the same time. Here’s a template that I’ve been using lately with great success:
<?xml version="1.0" encoding="UTF-8"?> <project default="4. Package Application" name="[Your Flex Project Name]"> <!-- Framework properties --> <property name="FLEX_HOME" value="[/path/to/your/flex/4.5/sdk]" /> <property name="AIR_GLOBAL" value="${FLEX_HOME}/frameworks/libs/air/airglobal.swc" /> <property name="ADL" value="${FLEX_HOME}/bin/adl" /> <property name="ADT" value="${FLEX_HOME}/lib/adt.jar" /> <property name="PFI" value="${FLEX_HOME}/lib/pfi.jar" /> <property name="FLEX_TASKS" value="${FLEX_HOME}/ant/lib/flexTasks.jar" /> <property name="LOCALE" value="en_US" /> <!-- Project properties --> <property name="project_root" value="[/path/to/your/flex/mobile/project]" /> <property name="class_path" value="${project_root}/src" /> <property name="lib_path" value="${project_root}/libs" /> <property name="splash_path" value="${class_path}/Default.png" /> <property name="app_name" value="[YourApp]" /> <property name="app_root_dir" value="." /> <property name="app_type" value="mxml" /> <property name="assets_dir_name" value="[name_of_your_assets_dir]" /> <property name="debug_mode" value="false" /> <!-- Certificate properties --> <property name="cert_loc" value="${app_root_dir}/[path/to/your/certs]" /> <property name="ios_keystore" value="${cert_loc}/[your_cert_name].p12" /> <property name="ios_pass" value="[your_cert_password]" /> <property name="ios_provisioning" value="${cert_loc}/[your_provisioning_profile].mobileprovision" /> <!-- Application properties --> <property name="swf_file" value="${app_name}.swf" /> <property name="air_file" value="${app_name}.air" /> <property name="ipa_file" value="${app_name}.ipa" /> <property name="app_descriptor" value="${class_path}/${app_name}-app.xml" /> <property name="main_class" value="${class_path}/${app_name}.${app_type}" /> <property name="build_dir" location="${app_root_dir}/build" /> <property name="debug_dir" location="${app_root_dir}/build/debug" /> <property name="publish_dir" location="${app_root_dir}/build/deploy" /> <property name="assets_dir" location="${class_path}/${assets_dir_name}" /> <property name="output_loc" location="${publish_dir}/${swf_file}" /> <!-- Use the Flex ANT tasks for easier compilation --> <taskdef name="mxmlc" classname="flex.ant.MxmlcTask" classpath="${FLEX_TASKS}"/> <!-- Clean existing directories --> <target name="1. Cleanup Directories" description="clean up"> <delete dir="${debug_dir}" /> <delete dir="${publish_dir}" /> <delete dir="${build_dir}" /> </target> <!-- Create required directories --> <target name="2. Build New Directories" depends="1. Cleanup Directories"> <mkdir dir="${build_dir}" /> <mkdir dir="${debug_dir}" /> <mkdir dir="${publish_dir}" /> </target> <!-- Compile SWF to build-directory for packaging --> <target name="3. Compile SWF" depends="2. Build New Directories"> <mxmlc file="${main_class}" output="${output_loc}" locale="${LOCALE}" static-rsls="false" accessible="false" configname="airmobile" debug="${debug_mode}" failonerror="true" fork="true" maxmemory="512m"> <source-path path-element="${class_path}"/> <compiler.library-path dir="${FLEX_HOME}/frameworks" append="true"> <include name="libs/*" /> </compiler.library-path> <library-path file="${FLEX_HOME}/frameworks/locale/${LOCALE}" append="true"/> <library-path dir="${lib_path}" includes="*.swc" append="true"/> <external-library-path file="${AIR_GLOBAL}" append="true"/> </mxmlc> </target> <!-- Package the application to an ipa file & save it in the publish directory --> <target name="4. Package Application" depends="3. Compile SWF"> <java jar="${ADT}" fork="true" failonerror="true"> <arg value="-package"/> <arg value="-target"/> <arg value="ipa-test"/> <arg value="-provisioning-profile"/> <arg value="${ios_provisioning}"/> <arg value="-storetype"/> <arg value="pkcs12"/> <arg value="-keystore"/> <arg value="${ios_keystore}"/> <arg value="-storepass"/> <arg value="${ios_pass}"/> <arg value="${ipa_file}"/> <arg value="${app_descriptor}"/> <arg value="${output_loc}"/> <arg value="-C" /> <arg value="${class_path}"/> <arg value="${splash_path}"/> <arg value="-C" /> <arg value="${class_path}"/> <arg value="${assets_dir}/icons/." /> </java> </target> </project>
UPDATED 3/23/11: changed the Package Application target to use ADT vs PFI now that AIR 2.6 is official.
You should only have to modify the values wrapped in brackets [ ] to match your system setup. Once that’s done, you’ll need to tweak your application’s descriptor file (ie, myapp-app.xml) as follows:
#1 Modify the initialWindow’s content value to match the output path from your ANT script:
<content>[This value will be overwritten by Flash Builder in the output app.xml]</content>
becomes:
<content>/path/to/your/application.swf</content>
#2 Add the following iOS-required data, either before or after the Android data section:
<iPhone> <InfoAdditions><![CDATA[ <key>UIDeviceFamily</key> <array> <string>1</string> <string>2</string> </array> ]]></InfoAdditions> <requestedDisplayResolution>high</requestedDisplayResolution> </iPhone>
After that, you should be able to compile your app using the ANT script without problem from any IDE that supports ANT or even from the CLI. This certainly isn’t the only way to accomplish this, it’s just my take on it. Feel free to hack away at it and share what you come up with.
If you should decide to bypass the template and build a script from scratch, here are a few caveats to remember:
ipa-test to ipa-app-store before publishing to the App Store.Checkout some of the related resources for alternatives to tackling the same problem and just general information on developing AIR applications for iOS devices.
RELATED RESOURCES
http://www.ivanalvarez.com/2010/10/flex-4-in-ios-3/
http://www.terrenceryan.com/blog/post.cfm/compiling-flex-hero-apps-with-mxmlc-in-ant
http://blogs.adobe.com/cantrell/archives/2010/09/packager-for-iphone-refresher.html
http://help.adobe.com/en_US/air/build/WS901d38e593cd1bac1e63e3d128fc240122-7ff2.html
http://help.adobe.com/en_US/air/build/WSBE9908A0-8E3A-4329-8ABD-12F2A19AB5E9.html
http://help.adobe.com/en_US/as3/iphone/air_deviphoneapps.pdf
I get the following error:
taskdef class flex.ant.MxmlcTask cannot be found
any ideas?
Sounds like ANT can't find flexTasks.jar
Does ${FLEX_HOME}/ant/lib/flexTasks.jar resolve to the actual SDK path on your system?
What SDK version are you using?
What ANT version?
What OS?
yes flexTasks.jar resolves to the actual sdk path, I am using the pre-release version 4.5 on mac osx, ant version is whatever the latest is that it 4.5 comes with
Hi Hasan, very cool post. Will you be publishing an updated script now that ADT has replaced PFI in AIR SDK 2.6?
Hello Hasan!.
I'm running iPad 1 (iOS 4.3.1).
I've sucessfully compiled the MXML mobile project. The app start but only display an app with the specified background color. (The framework seems to be not initialized)
I'm ussing Ant + Hero 4.5 + Air SDK 2.6. + Windows.
Any idea???
Hi Lunchx
I had a similar problem where it wouldn't show anything on the ipad, however, the emulator worked fine. I had to connect the debugger from flash builder to the app before the app started to work properly via the prompt on the ipad that asks you for the ip address of the local computer. Also, make sure the application is not cached somehow on the ipad. I had to remote it via the ipad directly and not through itunes and re-install it.
Thanks,
John
also luchyx,
make sure your app id in the app xml file is the same one you registered on the provisioning portal.
John
[...] http://labs.almerblank.com/2011/03/using-ant-to-compile-a-flex-mobile-project-for-ios/ [...]
[...] Using ANT to Compile a Flex Mobile Project for iOS – A definitive guide for the Ant relevant to IOS development in FDT 4 [...]