Access / load library assets from another SWF in Flash CS3

In this short article I would like to focus on a simple technique to load library assets from another SWF which is actually used as class container. I already used that technique several times and it comes in handy in some situations. In my opinion it is especially handy when you are working on a project with several people and one is doing the design of the assets to be used. It also can be handy when it comes to streamlined preloading of several assets. We use one SWF then as dataContainer for all the assets, the base swf loads the dataSWF and from then on the assets are accessible and can be instantiated.

Let’s illustrate the technique using a simple example:

Imagine we have one simple SWF (eg : data.swf) that contains one library item: a movieclip with a designed little square with a class name Square that uses Movieclip as his base class. As you know, in Flash CS3 a class is automatically generated when you not specify a custom class so in our SWF we can normally instantiate a Square object by writing this code:

var mySquare:Square = new Square();

But imagine that we have another SWF (eg: base.swf) where we would like to instantiate also Square objects. Thats were the technique of dynamic class loading comes in. First thing we have to do is to load the “data.swf” inside the base.swf like this:

var myLoader:Loader = new Loader();
var myUrlReq:URLRequest = new URLRequest(“data.swf”);
myLoader.load(myUrlReq);
myLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);

As you can see we call the onLoaded function when the data.swf is fully loaded. The onLoaded function is the place where we are going to access the SWF his contents, in our case the Square in the library. The final onLoaded function looks like this:

function onLoaded(event:Event):void
{

var Square:Class = event.target.applicationDomain.getDefinition(“Square”) as Class
var mySquare:MovieClip = new Square() as MovieClip;
addChild(mySquare);
}

As you see we first instantiate a class object and we acces the Square class (inside the library of the data.swf) and cast it as a Class also. From then on you can instantiate as much squares you want. To avoid flash saying that a square datatype isn’t found we cast a new Square object immediately to a MovieClip where it is extending from. The last thing we do is adding the square to the displayList by calling the addChild method.

Very simple technique but comes in handy in some situations 😉

Advertisements

40 responses to “Access / load library assets from another SWF in Flash CS3

  1. Michael 24 August , 2007 at 12:29 am

    Really interesting… thanks for the tip.

  2. Pingback: Bram.us » Access / load library assets from another SWF in Flash CS3

  3. ignas 17 September , 2007 at 1:03 am

    thank you very much!!!

    was looking for that all day.

    used to get same custom event class from loaded movie.

  4. Michael Prescott 19 September , 2007 at 4:40 am

    I’m having difficulty with this technique. I have several “skin” swfs. Each swf contains a CustomButton symbol, and each swf’s version of the button graphic is different. I can load swf1, create a new CustomButton() and add it to the stage to see it render. I then remove and destroy the custom button instance, then unload swf1. Finally, I load swf2, create new CustomButton() and add to the stage. The first swf’s butt graphic is drawn!! I’ve been able to “solve” the problem by wrapping each Flash generated swfs library items in a Flex generated swf using a class that @Embeds each library item into the wrapper. However, Flex is NOT a part of our team’s workflow and I don’t want to introduce it to everyone building skins. Considering the platform, the surely is a way to solve the problem with just the Flash IDE, right?

  5. Shahbaz Ali 1 November , 2007 at 6:21 am

    That is simple yet great solution along with good description.

    I wasted 4-5 hours to get help on Adobe’s site, blog, help files etc but failed to get any help.

    Thank you so much for posting such a great solution.

  6. JM 7 December , 2007 at 6:47 pm

    Thanks for this great technique.

    I’m able to load a symbol this way, and once it’s loaded I’m able to gotoAndStop on a certain label/frame within the attached symbol… but once the playhead get there there is another nested clip (named) and I’d like to use a goto within the nested clip… but this is not working. Tracing the nested clip yields undefined. Anybody have an idea how to access this nested clip?

    Thanks,

    JM

  7. Pingback: import external classes at runtime!! : devBlog

  8. Chetan Sachdev 12 March , 2008 at 1:36 am

    this works perfect. I am able to access buttons and MovieClips from library, please tell me how I can get Graphic assets, as they can’t be export for actionscript. Do I need to make them as MovieClip only.
    @JM do you get any solution for your problem ?

  9. Devendran 19 May , 2008 at 12:09 pm

    Than a Lot n Lot.
    i am new bee to AS3. i am trying this over 3 days….
    it showd undefied property even i am following the techniques which is showd in some website… At last you made it…

    thanks

  10. phil 3 June , 2008 at 4:54 am

    great tutorial, but how do I instantiate a bitmapData library object within the imported SWF ?
    I tried simply replacing the object type(MovieClip) with BitmapData within this line: var mySquare:MovieClip = new Square() as MovieClip; but it did not work.

    thanks for any help.

  11. owen 6 June , 2008 at 1:42 am

    Just been trying this out independently and came across this post. It’s pretty neat but I kinda want to take it a bit further. Basically I have a load of SWFs with different assets in them. So I load them in and then I can access the asset classes. Magic! But… it gets really boring having to type out all of the gefDef stuff for each class. I could load an XML file containing those names, but it’d be neater to be able to quiz the applicationDomain or the SWF and find out all of the classes within. Anyone found a way to do this??

    If these guys are listening…
    @Michael Prescott – you’d need to define a new applicationDomain for each of your skins. That way the new definition will be kept separate from the old one. smthg like:
    var appDomain1:ApplicationDomain = new ApplicationDomain();
    loader.load(url, appDomain);
    etc.

    @phil – You can’t access the bitmapData directly, so what you need to do is wrap it in a MovieClip, then draw that to a bitmapdata object. This will work:

    var Square:Class = appDomain.getDefinition(“Square”) as Class
    var square:MovieClip = new Square() as MovieClip;
    var squarebmd:BitmapData = new BitmapData(square.width, square.height);
    var squareBM:Bitmap = new Bitmap(squarebmd);
    squarebmd.draw(square);

    addChild(squareBM);

    • Jo 1 January , 2010 at 7:07 pm

      phil and owen: maybe it would be easier or simpler to cast the library image to a bitmap and then retrieve the bitmapdata.

      var img:Class = e.target.applicationDomain.getDefinition(“face1”) as Class;
      var img1:Bitmap = new Bitmap(new img(0, 0));
      addChild(img1);

    • Zdenek 29 January , 2010 at 2:16 pm

      ad Michael Prescott problem:

      I believe the correct usage of new application domain with loader would be:

      var appDomain:ApplicationDomain = new ApplicationDomain();
      var context:LoaderContext = new LoaderContext();
      context.applicationDomain=appDomain;
      loader.load(url,context);

      You cannot pass application domain as a second argument of the load method becaus it’s expecting loader context.

  12. owen 6 June , 2008 at 1:43 am

    that’s not supposed to be a smiley btw!

  13. Marc-andré 18 August , 2008 at 3:01 pm

    is there a way to replace an actual animated moviclip on the stage using this technique: in a way I can keep the animation of my movieclip but applying it to the newly loaded one form the other Swf.

  14. Elliot 12 September , 2008 at 3:55 pm

    Exceptionally useful, thanks

  15. Simon 16 September , 2008 at 7:19 pm

    Hi Koen and thanks for the info. I am particularly curious as to how to cast the square to a custom class that extends MovieClip (or Sprite for that matter). I am repeatedly finding that casting to a Custom Class results in square being returned as null?

    Thanks,

    Simon

  16. timbob 20 November , 2008 at 12:35 pm

    cool, just the last piece of the puzzle i was missing for this technique. thanks a lot!

  17. Pingback: Link utili sul caricamento di un SWF da parte di un altro | artBits

  18. Matan 16 July , 2009 at 12:01 pm

    i am trying to use this techniqe to get a custimized text input compontnt i created in the asset.swf – but i keep getting an error -‘ReferenceError: Error #1065: Variable TextInput is not defined.
    at flash.system::ApplicationDomain/getDefinition()
    at Main/onAssetsLoaded()[C:\matan\Projects\brits\chatApp\AS3\src\Main.as:56]’

    here is my line :
    var textinput:Class = e.target.applicationDomain.getDefinition(‘TextInput’) as Class

    your method worked perfectly on Sprites and Movieclips – but i cant seem to use it on components – please help

  19. James 12 October , 2009 at 7:26 am

    Yeah, I’m having HUGE problems casting from a custom class to a shared base class. I have a Widget class defined in the parent and child SWFs. When the child SWF’s document class is DerivedWidget, for example, any attempt to cast it to it’s base class Widget in the parent SWF results in NULL, even though Widget is defined in both the parent and SWF class, and the child is loaded into the parent’s application domain. Oddly, this WAS working fine until recently, and the code hasn’t change. I almost wonder if a recent Flash CS3 update broke it.

  20. Luke 12 October , 2009 at 11:26 pm

    Awesome! I’ve been wondering how to do this for years and always using hacky workarounds. This is a great solution – thanks!

  21. Shaedo 21 October , 2009 at 3:14 am

    THANKYOU!

    This is a superbly written tutorial! Very clear, easy to follow! Being able to do this has massively improved my coding!

  22. Galina 31 October , 2009 at 4:11 pm

    Thanks a lot! I need it very much!!!

  23. Ademar 13 December , 2009 at 6:42 am

    Thank You very much! I’ve been looking for this solution for a week and didn’t find anywhere! Now a solved my problem! I’m going to add your name at the credits of my site, if You don’t mind.

  24. Norm 27 January , 2010 at 3:46 am

    Solved a big problem, thanks.

  25. Chriddler 24 February , 2010 at 11:59 pm

    I was scratching my head wondering how to do this – thanks!

  26. Luigi 7 March , 2010 at 7:55 pm

    Very interesting trick, i tested it also in cs4 via AS3 and it’s perfect! 😀

  27. glassy 6 May , 2010 at 1:50 pm

    Wonderful!!!!
    The
    event.target.applicationDomain.getDefinition(“…”) as Class;
    was the missing link for me.

    Thank you!

  28. Zozel 3 June , 2010 at 9:42 pm

    Yes…this is just what I needed…but what do you do when the loaded SWF is not executable in the current applicationDomain.
    I have a SWF and lost it’s FLA – when I try to load it with the Loader, it gives me the error “TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at XXXXX”
    This error appears because my SWF tries to access a component that it’s null – not so surprising, since the SWF was ment to run on a webpage, not in a Loader object.
    How could I load the SWF into my ApplicationDomain, but without running, executing the code inside it? How can I instantiate my SWF’s classes without having to “play” the SWF on my page?

  29. Zozel 3 June , 2010 at 9:59 pm

    Also, I’d like to state that the Loader class has a major hole here – the most important classes that a developer would need to load from a SWF are not the ones of type DisplayObject, the simple ones, that are in lack of code – but the processing ones – the ones that are complex enough to cause problems when the loaded SWF is running on a foreign application domain.
    That’s why I think it is completely illogical that the loaded SWF’s inner code executes without giving you the possibility to choose whether or not you want it to execute.
    The ApplicationDomain idea – when I read about it on the internet it seemed an exceptional idea, but I ended disappointed by this “logic error” – the loaded SWF doesn’t need to be executed to give us the possibility to use it’s classes – what I;m trying to say is that it is most evident that an option like Loader.executeOnLoad option should have been be created – this had to be one of the first functions to create when the class was constructed.
    Anyways, the idea is brilliant, I believe – if the AS4 ( ;)) ) version will solve this issue I believe that the Loader class will be one of the most powerful updates for the AS language 😀

  30. Shreeji 28 July , 2010 at 6:25 am

    Hi,

    Thanks very Much……

  31. Isaac 4 August , 2010 at 5:37 pm

    Thanks man, this is a life saver!

  32. Jame Lin 13 August , 2010 at 5:08 am

    Thanks very very much. I have not found the solution for sult this problem at network for a while, but get at here, thanks.

  33. coolsegi 20 August , 2010 at 6:54 pm

    Thanks!
    that’s a nice tric. I need this in my project.

  34. Sukhrob 1 March , 2011 at 8:42 pm

    Hi,
    I have couple of questions:
    1. Can we have an access to the objects on the stage inside of the loaded swf (for example get them through instance name or name)?
    2. Is it possible to load swf file (with assets and some parameters) created in AS2 into AS3 project?
    Thank you,
    Sukhrob

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s