I've been developing a mobile application for a while now. It runs on iOS and Android as well as on the desktop as an AIR app. This is great and I'm very excited about it. However, last week I was asked why I couldn't export a version of the app that ran within a web browser. I said that I assumed I could and that I would look into it.
But why would you want to run mobile code on the desktop?
A couple of reasons:
- Greater re-use of code. This doesn't make sense in all cases but it does in many cases. (I won't elaborate because I think this is self-evident. If you disagree I'd be happy to talk about it but I'd rather not clog this description with it.)
- Quicker/easier client demos. Rather than having to install an apk or an ipa on a mobile device, I can just send a URL.
So what have I found? Well, from what I've tried so far.. it.. doesn't work. Or rather I haven't been able to make it work.
I started by creating a Flex Library project for all shared code. Then I created 2 application projects that reference it- one for mobile and one for web. The mobile project works fine but the web project does not. Here's what I've tried so far to make it work:
- I tried adding the mobilecomponents.swc and the mobile.swc theme to my web project so that Flash Builder knows about MobileSkin (and other mobile-only classes). This enables my app to compile but when I launch it immediately throws a runtime error inside of UIComponent:
VerifyError: Error #1014: Class flash.text::StageText could not be found
. I've found very little about this error, and the one tip I did find (adding the--swf-version=13
compiler option) does not work. - I tried using conditional compilation to control which class my skin components inherited from: MobileSkin or SparkSkin. This was just a quick experiment to see if it worked. I know it's disgusting and not a production solution. My thinking though was that if MobileSkin was really just an optimized version of SparkSkin, my skins should be okay inheriting from either. This didn't work right away- app wouldn't compile b'c certain methods were missing (ex. layoutContents) and so I bailed on it because it felt dirty to begin with.
- I tried replacing MobileSkin with UIComponent as the super class for all of my skins thinking that MobileSkin was probably just a lightweight subclass of UIComponent anyway. This approach resulted in some compiler errors at first (ex. no layoutContents method, no measuredDefaultWidth/measuredDefaultHeight properties, addChild vs addElement, etc.). Once those issues were resolved the app compiled but crashed with runtime errors inside of UIComponent's "getState" method. (Looks like MobileSkin overrides this method to prevent UIComponent's default behavior.)
So none of those approaches have worked for me so far... but what about you guys? Have you encountered this issue yet? Were you able to make it work or can you spot any obvious oversights I've made in the methods I mentioned trying above? Thanks in advance if you can.
Update: Issue Resolved
I've been able to make progress with the first route mentioned above: adding the mobilecomponents.swc and the mobile.swc theme to my web project
Turns out that Flash Builder had led me wrong in this regard. Adding the mobile SWCs to your Library project with the "merged into code" setting results in the compiler warning: The swc '/Applications/Adobe Flash Builder
4.6/sdks/4.6.0/frameworks/themes/Mobile/mobile.swc' has style defaults and is in the library-path, which means dependencies will be linked in without the styles. This can cause applications, which use the output swc, to have missing skins. The swc should be put in the external-library-path.
Seeing this the first time, I changed my linkage type to "External" and the warning went away. Then in my web project, I also added the mobile SWCs and set the linkage type to "merged into code" there. Flash Builder seemed happy with that approach, but upon running my application I got bizarre runtime errors (as mentioned above).
Turns out that my first attempt was the correct way. Set the linkage type on the library project to "merged into code" and then don't re-link from your web project. Flash Builder will warn you about it but ignore the warning. Things seem to work pretty well for the most part now! I have an issue or two to look into (ex. List component doens't scroll) but things look pretty promising overall!