June 1, 2009

ActionScript function for turning a date into a time interval

While working on a small Twitter utility, I wrote a function to turn a date into a time interval string. For instance, rather than formatting the date, it returns strings like "Just posted," "6 minutes ago," "4 hours ago," or "20 days ago". It's not a complex function, but I thought I'd post it here in case it might save someone a few minutes of coding. The less time we spend writing code someone else has already written, the more time we can spend innovating.

private function formatDate(d:Date):String
{
	var now:Date = new Date();
	var diff:Number = (now.time - d.time) / 1000; // convert to seconds
	if (diff < 60) // just posted
	{
		return "Just posted";
	}
	else if (diff < 3600) // n minutes ago
	{
		return (Math.round(diff / 60) + " minutes ago");
	}
	else if (diff < 86400) // n hours ago
	{
		return (Math.round(diff / 3600) + " hours ago");
	}
	else // n days ago
	{
		return (Math.round(diff / 86400) + " days ago");
	}
}

Posted by cantrell at 10:42 AM. Link | Comments (0) | References

September 17, 2008

Be careful how you call super()

Here's something all ActionScript 3 developers should know about extending classes and how parent constructors are called:

If class B extends class A, does class B have to call super() in its constructor in order to instantiate the parent class? Nope. What happens if you don't? The compiler inserts a call to the constructor for you. Usually.

The compiler just looks to see if you call super() at any point in your constructor. What if that call is inside of a conditional statement that evaluates to false? The default constructor won't get inserted, and the parent classes's constructor won't get called. Why is that a problem? You may very well get null reference exceptions since class level variables are often initialized in constructors. What's worse, you may only get them sometimes — only when your conditional statement evaluates to false.

Even if you determine that your code works whether super() is called or not, you still have to watch out. What if the implementation of the parent classes changes in the future? Code that used to work, and code that you could reasonably expect to continue working, may just break on you. I've actually seen this happen. It's not pretty.

How do you avoid this problem? Either call super(), or don't. Never put super() in a statement that may not execute, even if you find that your code works fine today since you never know what might happen to that parent class tomorrow.

Posted by cantrell at 10:41 AM. Link | Comments (6) | References

March 30, 2007

ActionScript 3 FedEx Libraries

I just checked some ActionScript 3 libraries into to Google code for accessing the FedEx web APIs. They aren't 100% complete, but they support a fair amount of functionality like:

The package is checked in as as3fedexlib. I expect to be adding additional functionality over time.

Posted by cantrell at 9:19 AM. Link | Comments (6) | References

March 28, 2007

vCard Parser in ActionScript 3

I just checked the vCard parser that I wrote for Maptacular into the as3corelib Google Code project. The entire project is available here, or you can go right to the vCard parser here.

It's simple, but it gets the job done.

Posted by cantrell at 3:18 PM. Link | Comments (7) | References

September 27, 2006

Getting Dictionary Definitions in ActionScript

There's a little known protocol out there called the "dict" protocol which enables clients to connect to a dictionary server and query it for definitions. Servers can (and usually do) host multiple dictionaries, many of which are specialized. For instance, a single server might host the "freedict" standard dictionary, some translation dictionaries, a thesaurus, and maybe a dictionary specific to computer jargon (FOLDOC: The Free Online Dictionary of Computing).

I wrote an Apollo application called "Lookup" which is a versatile dictionary client. It lets you choose a server, choose a dictionary on a particular server, and interactively query it. I'll release Lookup as soon as there is a public Apollo release, but in the meantime, I went ahead and checked the dict protocol library into the Adobe Labs source code repository. If you think you might have a need to look up words from ActionScript, check it out. It's not well documented, but if you start with the Dict class, it's pretty easy to figure out.

Posted by cantrell at 9:00 AM. Link | Comments (4) | References

August 17, 2006

ActionScript PNG and JPEG Encoders Updated

In October of 2005, Tinic Uro ported a PNG and a JPEG encoder to ActionScript 3. Shortly after, we added both to the collection of free ActionScript libraries on Adobe Labs. Tinic wrote them for an early alpha release of Flex Builder, so at some point along the line during the evolution of the compiler and the player, they stopped working.

I just checked in new versions of both that now compile and pass simple tests against the Flex 2 release. The PNG encoder is here, and the JPEG encoder is here. Let me know if you find any problems with them.

Posted by cantrell at 2:11 PM. Link | Comments (13) | References

July 27, 2006

A Proxy-savvy Socket in ActionScript 3

I'm working on an Apollo application that needs to make a TCP connection on a "non-standard" port, which, depending on your environment, usually means a port other than 80, 443, and few other commonly used ports. Development was going fine thanks to the new ActionScript 3 socket object until I went into the San Jose office to work for a day and discovered that the San Jose firewall is much stricter than the San Francisco one, and the port I was trying to connect on was blocked.

Fortunately, most environments with strict firewall rules also provide a way to get around them in the form of an HTTP proxy. After a little research and conferring with Chris Brichford, an Apollo engineer, we decided that this is a common enough problem that it would be worth solving in a generic way. So I wrote the RFC2817Socket class.

RFC 2817 "explains how to use the Upgrade mechanism in HTTP/1.1 to initiate Transport Layer Security (TLS) over an existing TCP connection." Not entirely relevant to our problem, however it also "documents the HTTP CONNECT method for establishing end-to-end tunnels across HTTP proxies" which means we can use a common HTTP proxy to make TCP connections on non-standard ports.

The RFC2817Socket class works exactly like the flash.net.Socket class, but if you give it proxy settings by calling setProxyInfo before calling connect, it will first handle the negotiation with the proxy server before dispatching the Event.CONNECT event. (If you don't set proxy settings, it will work just like the standard socket class.) All you have to know is your proxy server's hostname and port number, and RFC2817Socket takes care of the rest.

Unfortunately, this may not be the entire story, though. The reason I chose such a clumsy name for the class is that it will only work with proxy servers who adhere to RFC 2817. I suspect that most, if not all, proxies will use this technique (since it is a "standard"), however since I don't have a bunch of other proxies to test with, I have no way of knowing for certain. If it turns out that other proxies use different techniques for tunneling TCP connections, the thing to do would be to create other implementations in the same package, and then create a factory to return the right one. I'm hoping that the RFC2817Socket will work with most proxies out there so that won't be necessary, however if you find that it doesn't, it shouldn't be difficult to write one that does (if I can access the proxy that it doesn't work with, I'll even write it myself).

I should also mention that the entire tunneling portion of the RFC isn't implemented yet, so it doesn't do things like authentication and a couple of other things that are defined in the RFC. Adobe's proxy only uses the very basics, so that's all I implemented for now. If there's a demand for it, I'll add more.

For more information on how to get your hands on the RFC2817Socket class, or any of the other Adobe open source ActionScript 3 libraries, check out the this page on the Adobe Labs wiki.

Posted by cantrell at 10:41 AM. Link | Comments (3) | References

July 25, 2006

ActionScript 3 Makes My Life Easier

Now that I'm back and building Apollo apps, I'm obviously spending a lot of time with ActionScript 3 again. I've been using AS3 since there was a compiler capable of compiling it, but during my sabbatical, I wrote primarily Java and ColdFusion code. Now that I'm back, I have the pleasure of rediscovering all the things I love about ActionScript 3, and all the ways it makes my live easier than it was in the AS2 days:

Of course, there are a lot of other things about AS3 that I love . I know they've been thoroughly covered in the Flash blogosphere, but I'm having so much fun writing Flex 2 / ActionScript 3 code again that I couldn't help adding one more post. You can check out several examples of these things in action in the Adobe Labs source code repository browser (which I wrote in PHP, by the way, wishing the entire time that I could write it in AS3).

Posted by cantrell at 9:38 AM. Link | Comments (3) | References