We are loading external swf content into an adobe air application. Content is provided by an increasing number of third parties.
Being third party content, it will be loaded in a separate security domain (trustContent=false) and a sibling app domain (loadForCompatibility=true). We are doing this using the Loader class.
What are the features/options/approaches that would cause problems when using the swf as external content?
I am interested in any kind of issues, as we have already reproduced issues with content that occur regardless of the app domain / security domain where its loaded ( and occurs also in both Loader and SWFLoader).
Any workarounds for the issues are highly appreciated, especially ones that can be applied from the main app.
The big nasty problem (and one we've dealt with a lot!) is the fact that external SWFs simply can not be directly trusted. Ever. This makes communicating between them and the base AIR application difficult at best.
There is a hack around this based on loading the data of the SWF via a URLLoader and then taking the bytearray from it and pumping it into a Loader. However, I believe that hack was killed with AIR 1.5.1.
That being said, it is possible to communicate between the AIR app and the loaded SWF through what Adobe calls the sandbox bridge. However, setting up the sandbox bridge is a royal pain and any complex data (objects, even as simple as Arrays) get stripped down to generic objects on the other side of the bridge and can not be cast back to their original form.
For our recent projects that needed to use the bridge we created a specialty class called AIRBridge that you use on both sides of the bridge and it facilitates setting everything up properly. If you're interested, you can pull the current source from our Google Code project Automata-Tools.
One we already addressed:
Content outside of the external swf stage shows in the application, and when setting the size where it will be displayed the offstage elements are taken into account. Workaround: Add a mask on the main app so the external content is hidden. Use .content.width/height (full with offstage elements) and .content.loaderInfo.width/height (original stage size) to calculate how much to scale content so the original stage matches the visible area.
Related
Looking for a way for Javascript and Actionscript to share one copy of data in memory in a Flex Mobile app. Read on.
I'm building a Flex app where a portion of it is implemented in HTML/Javascript. In the browser, the SWF lives on the main page, and the HTML portion lives in an iframe, on that same page.
These two parts share about 1.5 MBytes of JSON data in the following way. The outermost page loads the data once, and defines a function that provides access to the loaded data. The Actionscript code uses ExternalInterface to call this function, and the HTML/Javascript code calls this function through its parent (which is the outer page). It's my assumption that both paths are accessing the same memory, and that I'm not actually marshalling data back and forth.
For the Flex Mobile version of this app, I'm using StageWebView to render the HTML part, which works well.
But I don't know how I can share data between the two sides.
Please note, I've looked at StageWebViewBridge, and I'll give it another look. But at a quick glance it looks like pushing data around, not like actual memory sharing. Am I wrong?
Considering we have already done the following actions:
Flex Framework as RSL
Compiling with debug=false
Loading most images at runtime
Drawing other simple images with flash draw features
Reducing complex images with pngquant
Creating modules for secondary features
Applying ranges to fonts
Running FlexPMD to find dead code and bad copy-paste
Running FlashOptimizer and secureSWF (with poor results)
Today our application is 1358k:
Code: 978k - 72%
Images: 270k - 20%
Fonts: 110k - 8%
We believe we spent a lot of time into asset optimization and most of the work is remaining on the code.
By analyzing our link-report, our guess is that the heavy part of the code is comming from Flex .mxml nested components. We don't think there is much to do on our pure AS classes.
Is there any analysis or coding best practice in order to reduce the impact of the code on the swf filesize ?
Thanks.
Here is the application : http://www.pearltrees.com/nicolas/137698/
In my practice I usually don't have big final swf files, so I want to mention only one thing. Using mxmlc directly we should not forget to add (for the final build of course) parameter/attribute
debug = "false"
in other way final swf will be almost 2 times bigger.
do you have an objects in the .mxml that are similar to each other that you could turn into a generic class and customize programatically?
Consider looking into preloaders and modules.
Without knowing your application, it's hard to be specific, but a custom preloader can sometimes help a lot with perceived download time. Let's face it, asking the user to idly stare at a progress bar is sad, and you can do better.
The usual example here is that your need your application users to login, or select some basic details before jumping into the main application. By implementation that first form as a preloader, your application will keep downloading in the background while your user interacts with that form.
The downside: Your preloader code doesn't have access to all the Flex goodness. You'll have to draw your UI and implement your interaction in plain old AS3. Still, the extra work can be worth it in some situations.
Flex Modules are the other thing that'd be worth looking into. In a complex Flex app, not everything is commonly used. If you cut the lesser-used bits from the main application and move them into a module you load on-demand, you may be able to save a fair amount of bytes from the initial download size.
I do a lot of work with GWT but don't have experience of Flex. I was talking to a guy today who was looking at moving some large Flex based applications to GWT due to the Flex application getting too big and using too much memory in the browser. This is a problem I have had before with GWT - browser apps using lots of memory as all the code gets loaded when it starts.
However, in GWT 2.0 there is now a code splitting feature to overcome the problem of the client code getting too big. This allows all the code (javascript) not to be loaded as one big file on start up but instead code split into different files that can be loaded when required.
I was thinking as to if there is anything similar in Flex. I assume the Flex application code all lives in one single SWF file which loads at start-up so this approach is not possible but thought there might be other solutions.
You might want to look into Modules. Otherwise the code is in one SWF. You can also move the Flex framework code out of yur SWF. And you can always dynamically load your resources such as images.
I have one swf file in that i used fscommand to get final output when submit button clicked in that swf ,
i am loading that swf in SWFloader in flex3 .i need to get fscommand value as Alert, how to get that value first and display as alert.
Thanks in advance
fscommand cannot be used for communication between loaded and containing SWFs.
From livedocs
fscommand: Lets the SWF file communicate with either Flash Player or the program hosting Flash Player, such as a web browser. You can also use the fscommand() function to pass messages to Director or to Visual Basic, Visual C++, and other programs that can host ActiveX controls.
You can call a method in the loaded swf OR access its properties directly OR use events OR use local connection to pass data between parent and loaded SWFs.
TECHNICALLY this is feasible, but a bad idea. You'd need to register a callback which would call the child swf (generally done from the child swf). But, you will risk a good deal of headache, and you'll have to rely a lot more on the browser than other options. It would also be slower than an AS only solution.
You're much better off (in this order):
Using a shared Singleton. This allows for complete separation of the two
swf's without requiring any major coordination between the two. The only
real potential problem can be caused if you want the child swf to have its
own ApplicationDomain, but even with that, there are work-arounds
Using events. This can work if you have the child swf dispatch a bubbling,
non-cancel-able event and have the event.target recorded by the
parent swf. You may have to adjust to avoid
SecuritySandboxViolations, however.
Using LocalConnections. The two detriments to LocalConnections are:
You will need to continually re-generate unique connection names to
avoid the error thrown by connecting two LocalConnections to the same
channel.
LocalConnections do have bandwidth limitations which can call
slowdowns if there is a high volume of traffic or if the messages are
too large.
Using direct manipulations like loader.content.foo.bar.baz;
I don't like this solution because it is much harder to maintain. It is
also much worse from a design perspective: you want to use
encapsulation as much as possible in this situation -- this technique
actively works against that.
How would you make the contents of Flex RIA applications accessible to Google, so that Google can index the content and shows links to the right items in your Flex RIA. Consider a online shop, created in Flex, where the offered items shall be indexed by Google. Then a link on Google should open the corresponding product in the RIA.
Currently the best technique for making an RIA indexable by search engines is called progressive enhancement (or graceful degradation, depending on which way you see it). Basically you create a simple HTML version of the application using the same data as the application loads. This version should be dynamically generated by some kind of backend server technology. This HTML version can be indexed by Google, but each page also contains a check that determines if the visitor is capable of viewing the rich version, and if so replaces the HTML content with the Flash, Flex or Silverlight application, preferably in such a way that the application starts in a state where it shows the same data as the current page. "Replaces" can mean that it just embeds the application on top of the HTML content, or that it redirects the user to a page that embeds it. The former solution is preferable, because the latter can be considered cloaking.
One way of keeping the HTML and RIA versions of a shop synchronized is to decide on a URL scheme and make sure that RIA uses some kind of deep linking technique. If a visitor arrives to a specific item via a search engine, say /items/345 the corresponding pseudo-URL in the RIA should be the same, so that you can embed the RIA on top of the page and set that URL as a parameter to make the RIA display that same page as soon as it has loaded.
This summer, Google and Yahoo! announced that they would begin using a custom version of Flash Player to index Flash based applications by exploring them "in the same way that a person would". Now, two months later there is still no evidence that this is actually happening. Ryan Stweart had to cancel his Flex SEO competition because it became evident that no one could win. The problem seems to be that event though the technique may very well work (although I'm sceptical), the custom Flash Player needs some kind of network interface to be able to load any referenced resources, like XML data, other SWFs, etc., and this is currently not implemented by Google. This means that for an application that loads all it's data dynamically, like say, all that I can think of, Googlebot will not actually see anything relevant. Yahoo! ignores SWF based content altogether.
Oh, and it just so happens that I talk about Flex and SEO on the latest episode of the Flex show =)
There is a massive thread available here:
http://tech.groups.yahoo.com/group/flexcoders/message/58926
But essentially, google already indexes .SWF files (you can test this out yourself by restricting search results to just .SWF files). It can search any text content within the SWF file.
However, if the text information in your site comes from a database / web server. Then it won't be able to access this information easily.
One example of getting this to work is using an XML file as your index page, then using an XSLT transform to render it using Flex. "Ted On Flex" has good information about this.
http://flex.org/consultants