Friday, December 3, 2010

Air for iPhone - loading external .swf files

If you are creating apps for iPhone with Air, you might have the need to load external .swf files.
In my case, it was the need to be able to have downloadable content.
I can't really think of another reason why you would want to do this, normally using .swc files is the way to go.

Anyways..

When you want to load an .swf file from an Air for iPhone application, there's some things you need to know.

Your .swf file cannot contain ANY actionscript whatsoever. Symbols in your library must also NOT be exported for Actionscript.

Adobe's documentation states that the scripting will simply be ignored, but that isn't exactly accurate.

If your .swf file contains Actionscript, the entire load will be ignored.
Which means you won't receive an Event.COMPLETE or even an IOErrorEvent.IO_ERROR when you try to load the file.

So, with no symbols exported to actionscript, all you're left with is animation on the timeline.


But I wanted to use it like a kind of library, where you could neatly pack all your graphics and animations and sounds in 1 swf, load it, and use the assets in your main program.

I've created a basic class to help with this.
Download StageLibrary with example project (flashdevelop)

This also works for android, but you have to change the path of the swf file.
Convenient if you create apps for android and iPhone that use the same assets.. if you're only creating android apps, you don't have the .swf scripting barrier that Apple enforces and can use library symbols like you usually do.


To create a swf file that will work with this class, create a .fla file of 1 frame in size.
and place all the symbols you want to use on stage and give them an instance name.

If you want to create a soundclip, make a movieclip, keep frame 1 empty, and place your sound on frame 2, making sure to add enough frames for the duration of the audio. If you don't add the extra frames, you wont be able to detect when the sound stopped playing.

StageLibrary takes care of loading the swf and collecting all instance names and allows you to quickly 'grab' a clip from stage, to use somewhere else in your app. (You can simply addChild() a clip from the library to your own stage/displayobjectcontainers)
I've also added a function to easily play a sound clip, that also has a callback when the sound is finished.

You can't reuse an object though, you aren't creating new objects, you're just moving them from stage to your app.
You can put more than 1 instance of a symbol on stage though, just make sure you give them a unique instance name.

It is also possible to use more than 1 frame in your main movie, but this has the effect of killing all animation of your objects (except for subclips with animations)

Check out the example project. It should be self explanatory, I even commented the code!
If not, post your questions/remarks here and I'll see what I can do :)




Thanks to Renaun Erickson, Seb Lee-Delisle and Joe Chung.

Also check out Renaun's blog entry with another loading example which helped me figure out what was wrong here


And finally, for those of you who like to tinker some more:
I've found that you CAN create multiple copies of an object on stage by changing frames of your main animation.
get a symbol from stage, go to frame2, go to frame 1 again, now you can get that same symbol again, and now you have 2 yaay.
Unfortunately, it screws up the animation in your object, except for subclips. But it could be useful to know ;)

Happy coding!