Recently I wanted to load modules into an AIR Application the same way I loaded them into the browser. Sadly for developers that want to accomplish this, there is a slight problem: the module cannot be loaded into the same security sandbox than the app, resulting in a very annoying error: "SWF is not a loadable Module". This happens because...
"due to (...) security restrictions (...), SWF loaded from another domain (...) go in a separate SecurityDomain, which means that it will have its own ApplicationDomain which means it cannot share classes with the main SWF and thus the ModuleManager can’t see the objects in the SWF as Modules." - Adobe Blogs.
So first of all, why would I want to do that if I can:
- Bundle up the modules into the AIR application and then use the AIR update framework to update everything;
- or use the standard way of achieving this, which is to download the modules and load them locally, so we have the same security domain.
Well, because:
- If I have a lot of modules that keep on being constantly updated, the AIR update framework cannot tell if the changes are in one of the modules, or in all of them, so every time I change a line in one I end up downloading the whole bundled application;
- I have the same application being deployed on the web and desktop, so I don't want to create two loading segments, depending of the client.
So in fact, I really want to use the same mechanics for both AIR and Flex, without using the AIR update framework for the modules. I will always end-up using the update framework for the main application, since there's no other way of updating it, unless I publish a new application manually and tell people to install it. I found Mihai Corlan's tutorial the most helpfull from the ones I've seen, so if you are interested give it a look. In case you're happy to download the modules first and loading them as local files, Adobe also has a guide for that.
So what about a solution?
Luckly, I've read a blog that has the perfect solution for this problem, at least at first sight. Aaron, the blogger, instead of using the normal combination of ModuleLoader and ModuleInfo, he loads the modules passing in a byte Array resulting from loading the module with the URLLoader and it simply works. You can download the full source code in his blog, since I would just be duplicating and copying this solution. However after some digging me and a friend found why this works and it's in fact documented in the livedocs:
"In AIR, by default the loadBytes() method does not let you load SWF content; it only allows you to load image content. In AIR theloaderContext property of the loadBytes() method has an allowLoadBytesCodeExecution property, which you can set to true to explicitly set allow the application to use loadBytes() to load executable SWF content. The following code shows how to use this feature:"
So everything is ok right?
No! Apart from the obvious problem that you are publishing an AIR application that loads unsigned modules and thus becoming very fragile to man-in-the-middle attacks is the fact that modules loaded this way have full access to the AIR SDK, which means mean people have all your OS available for hacking. Your AIR application might be a twitter client, but if it loads modules this way, you don't have any guarantee it's not doing whatever it wants with your local machine.
So, would I use this solution?
Depends on the application, but even if you trust a signed AIR application, you're still fragile to man-in-the-middle attacks that might inject modules that do the most crazy stuff with access to your OS. So, in the end I would probably let this go and have the hassle of having two loading methods, one for AIR and another for Flex, with signed modules. As tiring as it may be, I'm sure me and the application users are safe.
Still, nice solution in case is you want to pick it up. Cheers for Aaron on this.