Embedding Preferences/Settings Files In An AIR Application

When Building FCG, I encountered an unexpected problem. FCG lets the users modify the AS templates for code generation, so that they can customize their generated code.

We know that preferences/settings files are supposed to be stored in the applicationStorageDirectory of an AIR application. The AIR File API gives us a convenient way to read and write files into it.

The problem is that, as far as I know, there is no way to actually publish files into this directory during the application install process. The Flex 3 Export Release Version wizard does not allow us to choose the destination directory for files we choose to embed.

So the only workaround I've found was to embed the files into the applicationResourceDirectory, and them copy them into the applicationStorageDirectory, at start up.

The code is very simple, but here's how I did it.

At some point, I call a getTemplates() method which goal is to populate my TemplateManager with my template files content :

public function getTemplates(pDirPath:String):void
{
 
	checkForTemplatesDir(pDirPath);  
 
	//.. code to actually get the templates
	// in the applicationStorageDirectory
 
}

As you can see, the first thing I do, before getting the actual files in the applicationStorageDirectory is call a checkForTemplatesDir().

This method is responsible for both checking the availability of the files and, if they're not there (which should only occur the first time the application is launched), copying the templates to the place they belong to, ie the applicationStorageDirectory.

private function checkForTemplatesDir(pDirPath:String):void
{
 
	var f:File = File.applicationStorageDirectory.resolvePath(pDirPath);
 
	if(!f.exists) { 
 
		trace("Unable to find "+pDirPath);
 
		var f2:File = File.applicationResourceDirectory.resolvePath(pDirPath); 
 
		f2.copyTo(File.applicationStorageDirectory.resolvePath(pDirPath));
 
	}
 
}

Note that here I chose to use the File.copyTo() method and not the copyToAsync() method. This way, I only added one line of code in my getTemplates() method, and I can be sure that, after I call checkForTemplatesDir(), my files will be in the applicationStorageDirectory. Of course, I can afford to do that because I know the size of my template files is somewhat limited, but this should be the case for most settings/preferences files.

Now, there's one drawback to this approach. If the user updates for a new build of the application, this new release will not be able to replace the templates with new ones. But we don't want to overwrite the user's customized templates in the first place, so that's probably expected.

Anonymous on April 24th 2008

And for your next trick, do you know of any way to copy the file back out of applicationStorageDirectory to the normal-accessible filesystem or is this some form of AIR sandboxing? I read on the Flex888 forum that this applicationStorageDir translates to a hidden folder in your user's Documents and Settings/Application Data/application.xxxxxxxyyyyzzzzz location (for XP) which may prove to be a workaround, but so far I'm not having any joy getting another Flex SWF to be able to read that in via an HTTPService XML read call. I'll keep searching ... if anybody has any brainwaves on the subject then I'll be glad to hear. Darrell

david_deraedt on April 24th 2008

Good question, I don't know if this directory is somehow protected but if that's the case, I guess you'll have to first move your file to another directory such as the MyDocuments folder.

Anonymous on April 24th 2008

I forgot to mention, excellent post BTW ... after hours of headbanging and copying files back and forward into different locations, this finally explained it. Thanks. Darrell