<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>WebDeely &#187; SharedObject</title>
	<atom:link href="http://blog.webdeely.com/tag/sharedobject/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.webdeely.com</link>
	<description></description>
	<lastBuildDate>Thu, 18 Feb 2010 14:55:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Storing Custom AMF files for AIR Apps</title>
		<link>http://blog.webdeely.com/2009/03/storing-custom-strongly-typed-amf-files-for-air-apps/</link>
		<comments>http://blog.webdeely.com/2009/03/storing-custom-strongly-typed-amf-files-for-air-apps/#comments</comments>
		<pubDate>Tue, 31 Mar 2009 21:54:13 +0000</pubDate>
		<dc:creator>Chris Deely</dc:creator>
				<category><![CDATA[AIR]]></category>
		<category><![CDATA[Flash]]></category>
		<category><![CDATA[AMF]]></category>
		<category><![CDATA[SharedObject]]></category>

		<guid isPermaLink="false">http://blog.webdeely.com/?p=26</guid>
		<description><![CDATA[In my current AIR project I have a need to store persistent user data across sessions. Because the amount of data is fairly small, but the objects are complex, a SQL Lite database wasn&#8217;t ideal. I also couldn&#8217;t use standard SharedObjects because of the file size limitations and the fact that crashed our IDE (more [...]]]></description>
			<content:encoded><![CDATA[<p>In my current AIR project I have a need to store persistent user data across sessions.  Because the amount of data is fairly small, but the objects are complex, a SQL Lite database wasn&#8217;t ideal.  I also couldn&#8217;t use standard SharedObjects because of the file size limitations and the fact that crashed our IDE (more on that in a later post).</p>
<p>The solution I came to was to make my own SharedObjects, or rather custom files using the AMF data format.  It was actually much easier than I had initially feared.  I got my start by reading this <a title="The ABCs of AMF Format" href="http://ajax.sys-con.com/node/468744" target="_blank">article by Ted Patrick</a>.  (Unfortunately, the article is hosted on a Sys-Con property, and I&#8217;m not a fan of <a title="Sys-Con goes from bad to worse, launches Ulitzer, attacks community and content creators" href="http://aralbalkan.com/2022" target="_blank">their tatics</a>.)</p>
<p>Ted&#8217;s article is short and sweet and shows simply how to read and write AMF-encoded objects from/to a ByteArray.  Since we can easily save ByteArrays to disk and read them out again later, this is a perfect solution to the storage needs.</p>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #6699cc; font-weight: bold;">var</span> byteArray = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #009900; font-style: italic;">// the writeObject() method encodes any object into AMF</span><br />
byteArray<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">writeObject</span><span style="color: #000000;">&#40;</span> <span style="color: #000000;">&#123;</span> myBool<span style="color: #000066; font-weight: bold;">:</span> <span style="color: #0033ff; font-weight: bold;">true</span><span style="color: #000066; font-weight: bold;">,</span> myString<span style="color: #000066; font-weight: bold;">:</span><span style="color: #990000;">&quot;Hello World&quot;</span> <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
<span style="color: #009900; font-style: italic;">//the readObject() method decodes the AMF into a standard AS3 Object</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> myObject<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=object%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:object.html"><span style="color: #004993;">Object</span></a> = byteArray<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">readObject</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span></div></div>
<p>So, this approach works great if you are only using simple Objects made up of Flash Player core types.  Things get a little more complicated when you need to save complex custom objects.  AMF doesn&#8217;t automatically recognize your custom objects.  This effects all AMF transport methods, including SharedObject, LocalConnection and Remoting.</p>
<p>In order to inform AMF which classes it should recognize, you need to use the <a title="registerClassAlias" href="http://livedocs.adobe.com/flex/3/langref/flash/net/package.html#registerClassAlias()" target="_blank">registerClassAlias()</a> method:</p>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0033ff; font-weight: bold;">import</span> <span style="color: #004993;">flash.net</span><span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">registerClassAlias</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #0033ff; font-weight: bold;">import</span> com<span style="color: #000066; font-weight: bold;">.</span>webdeely<span style="color: #000066; font-weight: bold;">.</span>MyCustomClass<span style="color: #000066; font-weight: bold;">;</span><br />
<br />
<span style="color: #009900; font-style: italic;">// pass in the path to the class definition and a </span><br />
<span style="color: #009900; font-style: italic;">// reference to the actual Class</span><br />
<span style="color: #004993;">registerClassAlias</span><span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;com.webdeely.MyCustomClass&quot;</span><span style="color: #000066; font-weight: bold;">,</span> MyCustomClass<span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
<span style="color: #6699cc; font-weight: bold;">var</span> mcc<span style="color: #000066; font-weight: bold;">:</span>MyCustomClass = <span style="color: #0033ff; font-weight: bold;">new</span> MyCustomClass<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
mcc<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">message</span> = <span style="color: #990000;">&quot;Hello World!&quot;</span><span style="color: #000066; font-weight: bold;">;</span><br />
mcc<span style="color: #000066; font-weight: bold;">.</span>favoriteNumber = <span style="color: #000000; font-weight:bold;">12</span><span style="color: #000066; font-weight: bold;">;</span><br />
mcc<span style="color: #000066; font-weight: bold;">.</span>userName = <span style="color: #990000;">&quot;MiltonB&quot;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
<span style="color: #009900; font-style: italic;">// ByteArray will now recognize all of your custom class' properties, </span><br />
<span style="color: #009900; font-style: italic;">// and encode them to AMF</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> byteArray<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a> = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
byteArray<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">writeObject</span><span style="color: #000000;">&#40;</span> mcc <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
<span style="color: #009900; font-style: italic;">// ...and they can be decoded directly back to your class!</span><br />
<span style="color: #6699cc; font-weight: bold;">var</span> mcc2<span style="color: #000066; font-weight: bold;">:</span>MyCustomClass = byteArray<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">readObject</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span> <span style="color: #0033ff; font-weight: bold;">as</span> MyCustomClass<span style="color: #000066; font-weight: bold;">;</span></div></div>
<p>Ok, so now we have the encoding and decoding working properly, but we still need to save the file to disk in order for any of this to be useful.  For this we&#8217;ll use AIR&#8217;s File and FileStream classes:</p>
<div class="codecolorer-container actionscript3 default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;height:300px;"><div class="actionscript3 codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #0033ff; font-weight: bold;">import</span> flash<span style="color: #000066; font-weight: bold;">.</span>filesystem<span style="color: #000066; font-weight: bold;">.</span>File<span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #0033ff; font-weight: bold;">import</span> flash<span style="color: #000066; font-weight: bold;">.</span>filesystem<span style="color: #000066; font-weight: bold;">.</span>FileStream<span style="color: #000066; font-weight: bold;">;</span><br />
<br />
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> writeFile<span style="color: #000000;">&#40;</span> bytes<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a> <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><span style="color: #0033ff; font-weight: bold;">void</span><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; <span style="color: #009900; font-style: italic;">// save our data to the user's desktop, in a file called &quot;test.sol&quot;</span><br />
&nbsp; <span style="color: #009900; font-style: italic;">// &nbsp;btw, 'sol' is not a required extension, in fact you don't need an extension</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> file<span style="color: #000066; font-weight: bold;">:</span>File = File<span style="color: #000066; font-weight: bold;">.</span>desktopDirectory<span style="color: #000066; font-weight: bold;">.</span>resolvePath<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;test.sol&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
&nbsp; <span style="color: #009900; font-style: italic;">// Create a file stream to write stuff to the file.</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> stream<span style="color: #000066; font-weight: bold;">:</span>FileStream = <span style="color: #0033ff; font-weight: bold;">new</span> FileStream<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
&nbsp; <span style="color: #009900; font-style: italic;">// Open the file stream and write the data</span><br />
&nbsp; stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">open</span><span style="color: #000000;">&#40;</span> file<span style="color: #000066; font-weight: bold;">,</span> FileMode<span style="color: #000066; font-weight: bold;">.</span>WRITE <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">writeBytes</span><span style="color: #000000;">&#40;</span>bytes<span style="color: #000066; font-weight: bold;">,</span><span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">,</span>bytes<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">bytesAvailable</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #000000;">&#125;</span><br />
<br />
<span style="color: #0033ff; font-weight: bold;">private</span> <span style="color: #339966; font-weight: bold;">function</span> loadFile<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a><br />
<span style="color: #000000;">&#123;</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> bytes<span style="color: #000066; font-weight: bold;">:</span><a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a> = <span style="color: #0033ff; font-weight: bold;">new</span> <a href="http://www.google.com/search?q=bytearray%20inurl:http://livedocs.adobe.com/flex/201/langref/%20inurl:bytearray.html"><span style="color: #004993;">ByteArray</span></a><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> file<span style="color: #000066; font-weight: bold;">:</span>File = File<span style="color: #000066; font-weight: bold;">.</span>desktopDirectory<span style="color: #000066; font-weight: bold;">.</span>resolvePath<span style="color: #000000;">&#40;</span><span style="color: #990000;">&quot;test.sol&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; <span style="color: #6699cc; font-weight: bold;">var</span> stream<span style="color: #000066; font-weight: bold;">:</span>FileStream = <span style="color: #0033ff; font-weight: bold;">new</span> FileStream<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
&nbsp; <span style="color: #009900; font-style: italic;">// Open the file stream in read mode</span><br />
&nbsp; stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">open</span><span style="color: #000000;">&#40;</span> file<span style="color: #000066; font-weight: bold;">,</span> FileMode<span style="color: #000066; font-weight: bold;">.</span>READ <span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
<br />
&nbsp; <span style="color: #009900; font-style: italic;">// read the bytes directly into the ByteArray</span><br />
&nbsp; stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">readBytes</span><span style="color: #000000;">&#40;</span>bytes<span style="color: #000066; font-weight: bold;">,</span> <span style="color: #000000; font-weight:bold;">0</span><span style="color: #000066; font-weight: bold;">,</span> stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">bytesAvailable</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; stream<span style="color: #000066; font-weight: bold;">.</span><span style="color: #004993;">close</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000066; font-weight: bold;">;</span><br />
&nbsp; <span style="color: #0033ff; font-weight: bold;">return</span> bytes<span style="color: #000066; font-weight: bold;">;</span><br />
<span style="color: #000000;">&#125;</span></div></div>
<p>Hopefully this will be helpful to anyone faced with similar challenges.  I have found the de/serialization of the AMF objects to be extremely fast, reliable and convenient.  It works wonders and was a very quick switch over from the standard SharedObject process.</p>
<p>I have put together a simple Flex project file for an AIR app that allows you to experiment with the code here.  <a href='http://blog.webdeely.com/wp-content/uploads/2009/03/customamffiles.zip'>You can download the package here.</a> </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.webdeely.com/2009/03/storing-custom-strongly-typed-amf-files-for-air-apps/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
