Thursday, December 4, 2008

Loading SWFs at Runtime in Flex

Loading SWFs to an application at runtime all use Loader class in Flex. This includes SWFLoader and ModuleLoader which delegate to Loader class internally. Note that Modules are SWF files that can be loaded and unloaded by an application. Their loading is managed by ModuleManager which ensure that there is only one copy of a module loaded, no matter how many times you call the load() method for that module.

The Loader class can be used to load other external display assets such as image files (i.e., JPG, PNG, or GIF file) . Also you can use the URLLoader class to load text or binary data. However, we only focus on loading SWFs with Loader class in this article.

SWF files can be loaded over HTTP or from the local file system at runtime. There are four basic steps to using the Loader class:
  1. Create the Loader instance
  2. Create a URLRequest instance that specifies the SWF's location.
  3. Create a LoaderContext instance which has properties that define the following:

  • The ApplicationDomain for the loaded SWF
  • The SecurityDomain for the loaded SWF
  1. Pass the URLRequest instance and LoaderContext instance to the Loader instance's load() or loadBytes() methods.

When loading SWF files with the Loader.load() method, you have two decisions to make: into which security domain the loaded SWF file should be placed, and into which application domain within that security domain? When loading a SWF file with the Loader.loadBytes() method, you have the same application domain choice to make as for Loader.load(), but it's not necessary to specify a security domain, because Loader.loadBytes() always places its loaded SWF file into the security domain of the loading SWF file.

Security Domain Decision


The first decision to make is into which security domain the loaded SWF file should be placed. The choice of security domain is meaningful only if you are loading a SWF file that might come from a different domain (a different server) than the loading SWF file. When you load a SWF file from your own domain, it is always placed into your security domain. But when you load a SWF file from a different domain, you have two options. You can allow the loaded SWF file to be placed in its "natural" security domain, which is different from that of the loading SWF file; this is the default. The other option is to specify that you want to place the loaded SWF file placed into the same security domain as the loading SWF file, by setting myLoaderContext.securityDomain to be equal to SecurityDomain.currentDomain. This is called import loading, and it is equivalent, for security purposes, to copying the loaded SWF file to your own server and loading it from there. In order for import loading to succeed, the loaded SWF file's server must have a policy file trusting the domain of the loading SWF file.

Note that content in the Air application security sandbox cannot load content from other sandboxes into its SecurityDomain.

For more information, see the following:


Application Domain Decision



The second decision to make is into which application domain within the security domain that loaded SWF file is placed. However, you specify it only when loading a SWF file written in ActionScript 3.0 (not a SWF file written in ActionScript 1.0 or ActionScript 2.0).

Application domains are used to partition classes that are in the same security domain. They allow multiple definitions of the same class to exist and allow children to reuse parent definitions.

Every security domain is divided into one or more application domains, represented by ApplicationDomain objects. Application domains are not for security purposes; they are used to partition classes that are in the same security domain. If you are loading a SWF file from another domain, and allowing it to be placed in a separate security domain, then you cannot control the choice of application domain into which the loaded SWF file is placed; and if you have specified a choice of application domain, it will be ignored. However, if you are loading a SWF file into your own security domain (either because the SWF file comes from your own domain, or because you are importing it into your security domain) then you can control the choice of application domain for the loaded SWF file.

You have four choices for what kind of ApplicationDomain property to use:
  • Child of loader's ApplicationDomain. The default. You can explicitly represent this choice with the syntax new ApplicationDomain(ApplicationDomain.currentDomain). This allows the loaded SWF file to use the parent's classes directly, for example by writing new MyClassDefinedInParent(). The parent, however, cannot use this syntax; if the parent wishes to use the child's classes, it must call ApplicationDomain.getDefinition() to retrieve them. The advantage of this choice is that, if the child defines a class with the same name as a class already defined by the parent, no error results; the child simply inherits the parent's definition of that class, and the child's conflicting definition goes unused unless either child or parent calls the ApplicationDomain.getDefinition() method to retrieve it.
  • Loader's own ApplicationDomain. You use this application domain when using ApplicationDomain.currentDomain. When the load is complete, parent and child can use each other's classes directly. If the child attempts to define a class with the same name as a class already defined by the parent, the parent class is used and the child class is ignored.
  • Child of the system ApplicationDomain. You use this application domain when using new ApplicationDomain(null). This separates loader and loadee entirely, allowing them to define separate versions of classes with the same name without conflict or overshadowing. The only way either side sees the other's classes is by calling the ApplicationDomain.getDefinition() method.
  • Child of some other ApplicationDomain. Occasionally you may have a more complex ApplicationDomain hierarchy. You can load a SWF file into any ApplicationDomain from your own SecurityDomain. For example, new ApplicationDomain(ApplicationDomain.currentDomain.parentDomain.parentDomain) loads a SWF file into a new child of the current domain's parent's parent.

When a load is complete, either side (loading or loaded) may need to find its own ApplicationDomain, or the other side's ApplicationDomain, for the purpose of calling ApplicationDomain.getDefinition(). Either side can retrieve a reference to its own application domain by using ApplicationDomain.currentDomain. The loading SWF file can retrieve a reference to the loaded SWF file's ApplicationDomain via Loader.contentLoaderInfo.applicationDomain. If the loaded SWF file knows how it was loaded, it can find its way to the loading SWF file's ApplicationDomain object. For example, if the child was loaded in the default way, it can find the loading SWF file's application domain by using ApplicationDomain.currentDomain.parentDomain.

SWFLoader


If you are loading a SWF file using SWFLoader that comes from a different domain (a different server) than the loading SWF file, the secuirty domain decision will be made based on trustContent property on the SWFLoader object. If the trustContent property is set to be true, Flex will place the loaded SWF file into the same security domain as the loading SWF file. Otherwise, the loaded SWF file will be placed in its "natural" security domain, which is different from that of the loading SWF file. If trustContent property is set to be false and the loaded SWF file is placed into the same security domain as the loading SWF file, it also set the application domain to be child of the loader's application domain which allows the loaded SWF file to use the parent's classes directly. If any of the settings violate security restrictions, an securityError can be thrown.

ModuleLoader


Module files can be loaded over HTTP or from the local file system at runtime. However, a Flex module must be in the same security domain as the application (SWF) that loads it. For example, if the loading SWF is in a remote security domain, the loaded module will be placed in the same security domain as the loading SWF file; otherwise, ModuleLoader didn't set the securityDomain property in the LoaderContext. By default, modules are loaded into the child of the current application domain. You can specify a different application domain by using the applicationDomain property of the ModuleLoader class.

When you're using modules in an AIR application any module SWF must be located in the same directory as the main application SWF or one of its subdirectories, which ensures that like the main application SWF, the module SWF is in the AIR application security sandbox.

No comments: