Loading external SWFs into an Adobe AIR application - Best Practices? - apache-flex

I've recently been slated with a task to port an existing Flash Player-base game to a desktop app for publication on the Steam platform. The Adobe AIR framework seems like a logical choice for distribution, especially given the latest updates in AIR 3. Given the fact that I'm relatively new to flash/flex development, I've read through a fair amount of AIR documentation on the Adobe site in order to gain a better understanding of what the task involves. In general, I think I have a decent idea of what needs to happen, but there are a couple of wrinkles that may affect if/how it is even possible to port to the AIR framework:
The AIR application will need to load the actual game client from an external server due to the quick turnaround time of the client development.
Since the AIR application will be deployed on Steam, I want to use the Captive Runtime bundling that's available in AIR 3.0, i.e. no need for the user to 'OK' a separate AIR installation.
Have minimal impact on code changes within the external SWF as I'm not the primary developer of the game.
My first priority is to figure out the best approach for loading an external game client SWF into an AIR application. Initially, I tried to utilize Loader.load(), but that resulted in the following exception:
SecurityError: Error #2070: Security sandbox violation: caller http://localhost/MyClient.swf cannot access Stage owned by app:/AS3_AIRTest.swf.
at flash.media::SoundMixer$/set soundTransform()
at com.company.client.sound::SFXManager$/load()
at global/client.util::loadEmbeddedSounds()
at MyClient()
The offending code is:
static public function load():void {
SoundMixer.soundTransform =
new SoundTransform(Client.Settings.PlaySFX ? 1 : 0);
}
Upon hitting this exception, I decided to read up a bit more on the AIR / Flash player security domains. I have a much clearer understanding of why the exception occurred, but I'm still uncertain what the best approach would be to load the SWF and not receive the exception above.
After scouring through numerous posts on various forums, I found that a number of developers use Loader.loadBytes() to bring the SWF into the application sandbox. From an ease of implementation standpoint, I can see why many choose to go that route; however, I'm not inclined to pursue that approach due the potential dangers to user systems in the event that the external server is compromised.
The second approach that I've read about is that I can utilize a sandbox script bridge, and write an interface to grant certain privileges to the external client SWF. I'm hesitant to go this route at the moment because the game client is fairly complex, and I'm not entirely certain how much access it will require of the stage via different flash APIs. I haven't written this approach off as it sounds like it may be the best bet, but it could potentially be a large endeavor and I want to have minimal impact on the client SWF.
The final approach I've read about is by making an HTML AIR application. My understanding (sketchy at best) is that a SWF loaded via HTML (I believe in a frame/iframe) will have its own stage. My line of thinking is that if the HTML app loads a main page, which in turn has an iframe with SWF embed of the game client, then the client SWF will load in a remote security sandbox and have access to its own stage. My hope is that the SWF would behave as it does in the Flash Player.
This leads me to the following questions:
Is my line of thinking correct about the HTML app?
Would the client SWF have access to its own stage and pretty much behave like it does in the Flash Player?
Can HTML-based AIR applications be bundled with the captive runtime?
Can I use a traditional flex application with HTMLLoader to accomplish the same goal or does it need to be a full-blown HTML app?
If HTMLLoader can be used, would I need to provide the sandbox script bridge meta tags in the iframe tag?
Any help would be very much appreciated at this point. It seems like there are a number of options available, but I'm not sure which path is the right one to pursue at this point in time.
Thank again.
Josh

You have already investigated a lot. I was going to mention Loader.loadBytes technique but you mentioned that it is not secure. Actually, you could take care of security if you knew the signed hashes of the SWFs that may be downloaded. I remember to have read this approach in a AIR team's manager's blog but I can't recollect the link at this time. Basically, the approach would work if you knew all of the SWFs before hand that could be downloaded, and then generated their signed-hashs and put those hashes in an XML which shipped with the initial AIR app. Then, the initial AIR app can download those SWFs, compare their signatures and load them in application sandbox if it matches up with shipped hashes etc.

(Long question with lots of points, but here goes)
You are correct that passing the Stage object through a script bridge isn't going to work. So, removing the code that accesses the stage and possibly using the script bridge to get the job done in each specific case would be necessary.
If you embed the SWF in an HTML page, it will indeed get its own stage. It does not matter whether this is an "HTML-based" AIR application or an ActionScript-based application that uses the HTMLLoader. (Really the two are the same thing.) You don't need an iframe for this. This sounds like the easiest approach, especially if you aren't adding many AIR-specific features.
For information on signing, see http://www.adobe.com/devnet/air/flex/quickstart/articles/xml_signatures.html
The other thing I'd look at, if you haven't already, is what facilities Steam offers for doing such updates. Is the turn around time for uploading a new project/update to Steam really greater than the time it would take to add this post-install update system to the app itself? (I hope you aren't in one of those Dilbertian situations where, on paper, it looks like you can save time by doing weird things. In my experience, miracles created by dragging sliders around in Microsoft Project (or the like) don't pan out.)

Related

Accessing Environment Variables in flash

I know I cannot access environnment variables directly in Flash.
My project is a local swf file, run from flash player and not through browser.
The goal is to protect the SWF to be played from an unauthorized PC.
(this is my client requirements).
My idea was to embed it into an EXE (made in Delphi for instance) as activeX.
I am not sure it is the best solution.
I think AIR is even more complex to be done.
Besides, how to forbid the access of the SWF directly ?
Maybe embedding the swf any way ?
Any suggestions, tips are welcome.
regards
I'm going to preface this by saying that I don't think there's a 100% way to stop unauthorised access - if there was, there'd be no such things as pirated copies of windows, or flash. The best you can do is make it hard to hack.
Some suggestions:
You can actually access environment variables, by calling an external process in AIR, using NativeProcess (this link has a quick writeup: http://www.tikalk.com/js/get-windows-environment-variables-air-application) - but it's trivial to hack the .bat or add the env var
You can implement your own serial key system and give out keys to legitimate users. It would ideally need to be verified by a server call
You can code a "phone-home" server call - the app won't work without it. How you identify your users is really up to you; you could try via IP, but it's not perfect
You could disable local execution (check out SecureSWF), and run it online, behind a login wall
You could disable local execution, and run it via an intranet, so people in a company can use it, but not the general public
Depending on your app, on startup, you can download necessary files (content) from the web. This can either necessitate a login, or you can block unauthorised IPs. This is how Ubisoft DRM works on some of their games.
In a similar vein, you can download other SWF files that contain the actual logic of your application. These SWFs would only be stored in memory, never saved to disk
With all of these, the app can eventually be hacked open and modified (e.g. your server-check code could be removed, so the phone-home never happens). At the very least, run your SWF through something like SecureSWF (http://www.kindi.com/) to obfusticate the code before any public release.
It all comes down to how much effort you want to put into tackling the issue. For all the of suggestions that involve the internet, if the network is down, you won't be able to use your app, which understandably will cause frustration. For all of the suggestions that don't involve the internet, you will never know if it was successful or not.

How to turn a flex online application into a desktop application?

I we have been working for some years in a flex (cairgorn)+spring+blazeDataservice application using blazeDataservice to connect to the back end, now its getting kind of big and takes too much time too load, and people who use it, normally need it to use it regulary.
My country's internet bandwith is not getting better, actually it´s getting worse, so the app gets bigger and bandwith gets worse so loading it it's getting slower by the day.
I was wondering how could I get the client to be installed on peoples computers, I would be turning a flex online app into a desktop app WITHOUT REWRITING IT. I only need someone to point me in the right direction, i was thinking about 2 options:
1.- Can it be turned into adobe air ? is in´t adobe air desktop ?
2.- Maybe a flash that runs in peoples desktop ?
I need everything to work against the host spring backend just like it does today
Thank you very much!
Just to be clear:
If it is the size of the app (SWF) itself, rather than the queries being performed, an another alternative to speed things up, without building a Desktop (AIR) version, would be to use what Flex calls Modules.
Basically you would be breaking your app into smaller pieces that get loaded only as necessary.
If you do go the Desktop (AIR) route, you may also want to explore a local SQLite database that Syncs with your server only as needed, thus further reducing the internet connectivity issues.
This would of course add to your development time, but it seems like it might be a good bet given the situation you describe.
As for where to start, switching from a Web to a Desktop (AIR) app can be as simple as changing the main MXML tag from (in Flex 3) mx:Application to mx:WindowedApplication and launching your app.
UPDATE in response to follow up question:
Hard to say how much rewriting would be involved without knowing how your code is currently structured, but doubtful it would be a major rewrite.
As an experiment, I would suggest the following:
Create a new Flex application.
Create a new Module.
Add some simple MXML and Actionscript to the Module.
Add an instance of the Module to your Main view.
Run/Compile.
What you should see is that you might as well have not wrapped it in a Module at all, from a functionality or coding perspective, but the Module will have been compiled into a separate SWF, and Flex will handle loading it as needed.
If that all works and makes sense, I would start breaking up pieces of your code into Modules and see if that begins to solve your problem.
Adobe AIR is the right way to go. It is essentially #2, and often you can pretty much just publish exactly what you have straight to AIR instead of the web, and it just works. Fancy!

Create fat client (RIA) with HTML - controlled environment

I realize that this question can start a discussion but that's really not my intention. We've created a Flex Application to take tests from candidates. The advantage of the Flex Application is that all state can be stored in the application running in the browser of the client. Things like time limits, navigation, scoring, ... can all be handled within the application without us having to worry about a back button for instance. Even running the app offline with Adobe Air isn't that hard.
My question now is if such an application could easily be made with HTML, Javascript, Ajax, ... ? The reason I'm asking is because an application in HTML would be much easier to distribute on Mobile devices for instance. Also, our domain model for instance is mostly implemented in AS3 (Flex) so using it along the server side means porting it to C#.NET. (with two codebases as a result).
Look at any good MVC toolkit, you will easily be able to handle this. Castle project is good as is Microsoft MVC, both of which allow you to choose from a variety of view engines to handle the actual page rendering thereby allowing you to choose the most 'mobile efficient' engine...
As for the technicalities, you would store all persistent data in a server session object.

Advantages/Disadvantages of AIR vs Flex/Web

I'm tasked with writing an application for placing and connecting objects (sort of like a room planner where you can place furniture). I've made a demo using Flash Builder 4 and built it for AIR as a desktop app. Now the client wants the full app, but they and I am unsure whether to continue building it as an AIR app or transform it to a web application using Flex. I tried making a simple conversion of the AIR app to a web app, and most things worked but not all. The things that don't work seem to be simple bugs, though, not complete lack of capability.
The capabilities that I'm going to need (except for the modelling) are:
Printing of the finished image + a list of the furniture that has been placed
A way to save and retrieve finished plans
A way to export the list of furniture to Excel format
Handling a whole slew of data about the different objects
Only the printing has been implemented so far, and seems to work in the web app as well.
What advantages/disadvantages are there with the two approaches? Are any of the capabilities I need much worse (or even impossible) to implement in either approach?
Edit: Thanks all for your answers. From them, and my own research, I came up with the following:
Web app
Advantages
Accessible, no need for installing software
Easy to keep up to date
Disadvantages
Requires Flash 10 (for saving files)
Requires a web server to serve content
Sligthly longer development time (from where I am right now)
Requires an internet connection to work
Lots of data transport, may be slow on a slow network
Desktop AIR app
Advantages
Slightly faster development time (from where I am right now)
No web server necessary
Can be used while not connected to the internet
All data is local and faster to load
Disadvantages
Requires the Adobe AIR runtime + a separate installation of the program
Updates need to be distributed to all users and an admin needs to install them
There is no one straight answer for this one. A few points to consider:
If you want to use specific AIR features like offline usage, integration with the user's OS etc, you should use AIR (of course)
Flex applications are more easy to distribute and upgrade, because everyone uses the same swf instance from the server. When using a server backend with AIR, you should be aware of possible backwards compatibility issues when upgrading you application.
There are a lot of little differences, but in broad strokes, the only considerations you have to think about are:
Does it need to be on the Web?
Does it need file system access.
If (1) then use regular Flash. If (2) then use AIR.
The biggest disadvantage is related to the update model - you need to be a super user in order to update the air application - especially in enterprise the users of the AIR applications don't have rights to update it. If your application is running in the browser you do not have this issue.
Besides that, I do not see any disadvantage.
Check out flash 10 FileReference you can let users save results easily to their local file system. I've used it to create PDF's and let the user save that for printing.
For the PDF side I used Alive PDF.
protected function PrintCard(event:MouseEvent):void
{
//ShowHideBorders();
var printPDF:PDF = new PDF( Orientation.LANDSCAPE, Unit.MM, Size.LETTER );
printPDF.setDisplayMode( Display.FULL_WIDTH, Layout.SINGLE_PAGE );
printPDF.addPage();
printPDF.addImage(CardPanel);
var fileRef:FileReference = new FileReference();
fileRef.save(printPDF.save(Method.LOCAL), "card.pdf"); // Sends the file to the USER
//ShowHideBorders();
}

Could Facebook have been implemented in Adobe Flex?

I am considering creating a website with the complexity of Facebook that should be able to scale into the millions of users. My question is: Is there any reason not to use Adobe Flex for such large project apart from the obvious point of requiring everyone to have Flash installed and not having to rely on Adobe? In my view Adobe Flex would reduce the server load for Facebook, because more of the work could me done on the client side. Do you agree?
Of course Facebook could have been implemented in Flash. But then the question is would it have succeeded? There are reasons big web companies like Google, Facebook and Yahoo only use Flash as sparingly as possible.
The thing I would fear most is alienating users. The Flash plugin isn't the best piece of software out there. It is slow and likely to crash once in a while. If your app gets bigger you might get some loading times that might not be acceptable to your users. Also in my opinion full Flash sites just don't feel right because they behave differently from HTML websites. All great websites like Google, Flickr, Stackoverflow or Facebook feel very light and slick which is very elegant makes up for great usability.
And then HTML and JavaScript are a lot more flexible. Do you want your website to be available on smartphonse? The iPhone has no Flash and even with phones that do you have the problem that users will very likely hate a full Flash site since those phones don't necessarily scale Flash as nicely as they scale HTML and Flash draws battery like crazy. If someone comes up with another revolution like smartphones you can be sure it supports HTML and JavaScript but you can't be so sure about Flash.
Then the question is how would you gain any efficiency? Of course you can write your UI with Flex and just call very lightweight webservices like you would use them for AJAX and you can even cache some of the content of the site locally so that you don't transmit more data as necessary for user interaction (the UI is transmitted only once). But you can also do that with JavaScript. You can write your UI in HTML and JavaScript, load it once and then just pull the naked JSON data from the servers and render it using JavaScript. You can also fetch lots of this data in advance to get the number of requests down. But still such an approach has its cons. Did you ever notice that when you type an answer on stackoverflow and someone else submits an answer you get notified while typing your answer. Such real time features are very cool and you might want this at some point in time which means more server interaction.
But whatever you do your servers still have to scale if your site grows. Even if you minimize the number of GET requests that hit your servers they will still grow a lot when your site gets popular and you will need a lot of servers to handle you will just improve your users/servers ratio.
The most interesting point though is that Flex is much easier to program than AJAX (think about browser incompatibilities for instance) and still AJAX was not only invented but the whole world messes with all those problems that come with it instead of using Flex. I think this tells a lot about of the value of the result you get when creating a full website in Flash.
Go to facebook and do view source...do you see all that JavaScript? That all runs client side
Johannes is right to point out the difference for server vs. client. The server side stuff is what needs to scale.
As an example, the Microsoft Silverlight team has assembled a facebook client app in silverlight (using the Facebook public API). My point is, using todays technologies, it is entirely possible to write a web application targeting many different kinds of client technologies: classic web browsers (HTML/javascript), 'rich internet applications' (flex, silverlight), ...
See also the myriad of Twitter clients out there.
The company I work for has a large app in Flash that is used by Governments. It is very hard to maintain and does fail sometimes. The problem is all of the .fla and .as files that have to be altered just to make a small change. Yes, the app could have been built better but even so, it is still harder to maintain than an HTML/JavaScript front end.
While I love writing Flash/Flex apps, I believe they should complement a site and not be the site.
Using a good JavaScript framework like jQuery takes the Browser compatibility question out of the picture (for the most part) and allows a lot of functionality.
Flex is the GUI for the client. You still need server-side storage and that's what has to scale. The user interface could be in Flex, while most of your users won't like such interfaces.
You will have to do a custom version of your site for the iPad/iPhone.
There are other ways of moving load to the client side. Javascript will give you porting headaches, but less than moving away from the entire architecture like Flex.
OTOH when you get a million users you'll have the resources to reimplement your site.
I don't think you would see a performance advantage with a site like Facebook, because the content is highly dynamic, comes from many different places, and is created by many independent entities. Flash (and therefore Flex) is better for monolithic apps from a single source that don't need to change very often.
The default in Flash is to build everything into a single .swf file that holds everything. It is possible to break out of this default behavior, of course. You can make web service calls, pull in external components via the SWC mechanism, load static content via HTTP, etc. Nevertheless, it's not the default pattern, which affects how Flash development libraries and tools work. Besides, the more of this you do, the less of the "run everything we possibly can on the client side" benefit you get. It gets soaked up in HTTP connection overhead.
The default on the plain old standards-based web is to store all assets separately and assemble them dynamically at the client. This is one reason the web is slow -- again, all that HTTP connection overhead -- but also why it is flexible and dynamic. It mates well with a site like Facebook which requires constant evolution by a lot of independent developers.
I say this having developed a Flex app, which I am happy with. Only one person -- me -- has to maintain it, and it's naturally a monolithic app. It plays right into Flex's strengths.

Resources