Flash is a great platform. You can build applications for the browser, the desktop, and… well, what else is there?
When building applications, especially those with a document-based model such as the Aviary apps, Odosketch, My Canvas, ZenStudio, the apps on acrobat.com, and many others, you need a file format for the document or project. Or some way to save it.
What Not To Do
You don’t want to save each item into a table in the database. I know a guy…who had a dream…that his friend did this. This guy’s friend in his dream had a table for each item that needed to be stored with foreign keys etc. When a project needed to be loaded, the server-side script did a ton of queries and created a sometimes-quite-large XML structure that it then sent to the Flash app. When saving, this XML was sent back and parsed back into the database with INSERTS and UPDATES.
That does not scale, and none of that data was needed to be pulled up in reports or anything that you might consider useful and require a database for. It was complex, hard to add features, and slow. That is, it would have been had that guy’s dream friend been real.
Warmer, warmer
Saving document/project files to disk is the way to go. You can store metadata about each project or document in a database if you are storing them server-side. If it is an AIR app, give it a unique extension and the user can double-click on the file to open it. If you are AIR only, you can save your file as a SQLite database file. Pretty sweet option, but doesn’t work for the browser ’cause Flash can’t do that. The format could be XML like OpenOffice documents and the new MS Office formats. You would need to parse the files in and out and they could get very large, so you’d want to compress them anyway.
Hot, burning, you’re on fire!
So, XML might be the most portable format, but hey, that’s what Import/Export dialogs are for, right? We’re talking about Save/Save As… :) Enter our new contender, AMF! AMF isn’t really new, however I haven’t heard of many people using it as their file format. The cool thing about using AMF is that after you’ve prepared your objects for it, you could store (in player 10) pieces of your document on the clipboard for copy/paste from one place to another (even after a page refresh or from AIR to browser!). You can do an auto-save of a document or page to the user’s SharedObject store.
Preparation and implementation
To use AMF as the format for you data you’ll need to prepare your objects sufficiently. Here are a few rules:
- No required parameters in your constructors. When AMF unserializes it has to create those objects and assign the public properties to it. You’ll get errors otherwise.
- Register your classes usingĀ flash.net.registerClassAlias or [RemoteClass(alias="...")]. This will store the registered alias name to map a class to a string for serializing and unserializing.
- Use IExternalizable for more complex items that only need a few properties stored, or for Flash classes that can’t be stored (e.g. BitmapData). This allows you to get around the constructor parameter issue, but it is more work. :)
- Make sure any data you need stored is a public getter/setter or you’ll have to use IExternalizable. AMF serialization will only store data that is public and read/write. If you think about it, it makes sense.
The way to store your document object or project object (or page, or widget, or whatever) to AMF depends on where you are storing it. There are a lot of Flash APIs that use AMF already. If you are storing it to SharedObject, just assign the item to the data property or one of its properties.
SharedObject.getLocal("_myProject").data.project1 = myProject;
To send it from one app to another over LocalConection is just as easy.
var conn:LocalConnection = new LocalConnection();
conn.send("_connName", "passProject", myProject);
To send it to the server vi Flash Remoting you pass the object as-is the same as with LocalConnection.
If you want to save the project to disk or pass it to the server in a RESTful manner or as a file upload, you’ll need to serialize it to AMF first. But that is pretty easy. Just remember to compress after you write it and uncompress before you read. This will save a lot of room.
var byteArray:ByteArray = new ByteArray(); byteArray.writeObject(myProject); byteArray.compress(); // write the bytearray to file or send to server // or we can pull it back out making a clone! (save as...) byteArray.position = 0; myProject = byteArray.readObject();
Easy cheesy. I will leave it as an exercise to the reader to figure out how to store it to the clipboard for copy/paste.
XML might be an easier format, though more verbose and prone to errors in the creation and parsing. Though it could allow for greater flexibility and accessibility to other programs to read the file.
Let me know if you use AMF for your document/project file storage. I’d be interested to hear how many people use this method and how well it has worked out for you.