I recently was tasked to get part of an older Flex 3 application onto an iPad. Why not, right? I mean, FlashBuilder 4.5.1 and AIR 3.0 are awesome… This should be cake, right?

There’s a lil gotcha – Flex 3, or MX components, ooorrr Halo components, are not exactly welcomed on Mobile.

Fret not! I’ve figured out the task, and it’s rather simple.

HALT! WHO GOES THERE?

Sorry to break the bad news, but there’s a good chance this post won’t do you any good if you’re on Apache Flex.

As the Apache Flex team has made decisions, they’ve slowly been ripping out the MX components, and I’m having people email and tweet me with questions regarding why their app still won’t work.

Simply put, the component is forever gone.

I submit the following for review:

Is there a solution?

I don’t know, and I’m not going to find out… I don’t do Flex anymore (not exactly by choice, but that’s another post).

The only solution I can possibly think of is determine which components you need, and their dependencies, and rip them out into their own library and give them a custom namespace. com.killerspaz.flex.mx is probably what I’d use. Then you just need to change all your references and imports to reflect the new namespacing and it *SHOULD* work. The thing is, you might need to go all the way down to UIComponent for it to work, which will bloat your app pretty significantly.

Anyway, on with the rest of the show…


Why and how are they removed?

Well the why of it is simple. Performance and interaction. Granted, we now had Flex 4 which also allowed for virtualization for most complex components, it didn’t have what we needed: speed and interchangeability between desktop and mobile. A 1-stop shop, if you will. Flex 3 was stuck in the days without touch; thus the lists would all be scrollbars, and no dragging. Not to mention how scrolling used to be handled (yuck!).

As for how… It’s a combination of the mobile theme, and the lack of including it. LOL!  You can compare yourself the build configs for Flex (flex-config.xml) and AIR Mobile (airmobile-config.xml) and see how one includes the mx.swc, while the other doesn’t.

Flex 4 completely reintroduced skinning by separating behavioral and display logic. This is a good thing, especially for mobile where devices have many variant display types. All you need to do is change skins for a different platform/device, and you’re golden. But sometimes we have components that are completely custom, but utilize mostly-light components (i.e., Button, ProgressBar, Container, etc. Basically, not a lot of lists, charts, data rendering, etc. Really custom UIs). Certainly it can’t be THAT bad, right? As it turns out, not for me, no. If you keep it simple and lightweight (i.e., no extra containers, and as close to a flat Display List as possible), it should be OK. That’s my official blessing – if it doesn’t work for you, I blame you! 😛 No really though, it’s not supported by Adobe.

So tell me how to fix it already!

OK, it’s actually very easy. I’ll be using the default paths for Windows users, but this should all translate easily for everyone.

Missing Components

First thing is to include the MX components swc:

  • Right-click your project > Properties.
  • Click Flex Build Path > Library Path tab.
  • Click Add SWC button, and point it to: C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.1\frameworks\libs\mx\mx.swc
Failure to do this step, and probably what brought you to this post in the first place, results in something like the following run-time error:

VerifyError: Error #1014: Class mx.skins.halo::ButtonSkin could not be found.
at flash.display::MovieClip/nextFrame()
at mx.managers::SystemManager/deferredNextFrame()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\SystemManager.as:284]
at mx.managers::SystemManager/preloader_preloaderDocFrameReadyHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\managers\SystemManager.as:2633]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.preloaders::Preloader/timerHandler()[E:\dev\4.5.1\frameworks\projects\framework\src\mx\preloaders\Preloader.as:515]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()

Missing Skins

Next is to source the path to the skins for the defaults.css included in the SWC:
  • Open properties tab if you closed it… Duh.
  • Click Flex Build Path > Source Path tab.
  • Click Add Folder button, and point it to: C:\Program Files\Adobe\Adobe Flash Builder 4.5\sdks\4.5.1\frameworks\projects\mx\src
And failing to do this step yields roughly 26 errors (at least for me) indicating the following:
  • 1120: Access of undefined property BorderSkin.
  • 1172: Definition mx.skins.spark:BorderSkin could not be found.

Anything Else?

You don’t actually need to include the SWC. The source alone will cut it. But I came across the solution in this way, and it shows how the SWC alone doesn’t cut it, but the source does.

Other than that, that’s it! If you run into other components needing included, do essentially the same thing for the proper SWC. If you don’t know which one, feel free to ask!