I’m using the Flex 4.6 SDK and compiling .SWF files with it. Occasionally, I add an SWC library to my projects, and usually they behave normally – whether they are external libraries or internal libraries (In FlashDevelop, right click the SWC file, hit options, and you’ll see the choices there).
Recently, I’ve been using a lot of products from MilkManGames to help my AS3 applications take full advantage of mobile features. As I became more and more reliant on them, I realized I had – at some point – crossed a line where my applications would start crashing on launch on mobile devices… But only when compiled to native bytecode (as opposed to content projector, aka the “fast compile”).
I’ve actually been banging my head against this one for 4 or 5 months. It’s kind of a problem, because content projectors run more slowly than native bytecode. And, more seriously, it’s against Apples TOS to submit content-projector items to the App Store.
In a fit of frustration, I submitted the latest version of IceBurgers to the iOS market as a content projector and Apple didn’t notice, so that’s why you can buy it today. It’s still against the TOS and they could technically pull it at any time, so I still wanted to get to the bottom of this. The fellows at MilkManGames were quite patient and tried all sorts of things. FlashDevelop support couldn’t help. Twitter was no use.
Well, last night, I finally figured it out.
It’s a pretty serious bug in the Flex compiler (and/or a really shitty intended feature?), that only kicks in when your project uses a PRELOADER. Here’s a screenshot of my Main.as file:
You can see I’m using the compiler-command factoryclass method to import a preloader at runtime. I also picked a random .SWC file to include, in this case it is the SilentSwitch utility. I’ve instructed the compiler to include SilentSwitch as an external library – that is, I intend to bundle the ANE file together with it at some point, and I don’t want it to import the library into my compiled .SWF file.
This works as intended, so far.
But if, in the preloader file, I make a reference to SilentSwitch… It will include the SWC library into the SWF file. If I were then to compile it together with the ANE file and make a native IPA file for iOS release, the incorporated ANE classes conflict with the precompiled SWC classes (they are one and the same) and the app will CTD. (haha, that was a lot of acronyms!)
If you’re having trouble following, and have a copy of FlashDevelop, just check out this project I put together. If you don’t have FD or the appropriate compilers handy, I included two SWF files in that archive – one compiled each way, so you can explore and see that the assets were included in one and not the other.
I’m guessing that when the Flex compiler encounters a FactoryClass method, it forgets the compiler instructions for including things externally for some reason.
I’ve filed an official bug report, but in the meantime there is a quick and easy solution: Move all of your SWC references out of any factoryClasses (preloaders) you may have.
Edit: It appears this is a terrible tech limitation of the Flex compiler, and is pretty-much working “as intended.” You are expected to put all external libraries in frame 2… Of course this behaviour is not documented anywhere, and no tutorial mentions it as a gotcha. :)