Technical Post-Mortem of First Release

So. We built a Plazes client. How did that happen?

Update: added information about the Google Maps integration

Adobe AIR

Apart from building something we really wanted for ourselves, we also wanted an excuse to work with some new technology we hadn’t touched before. Combined with all of us not having any real experience with building desktop apps, we chose to use Adobe AIR and work with HTML/Javascript.

All in all it was a pretty pleasant experience. We really loved being able to get something nice fast and also to not have the problem that your HTML/CSS has to work in multiple, often broken, browsers. That certainly saved a lot of time ;)

The AIR Introspector (Adobe AIR’s equivalent of Firefox’ Firebug, Opera’s Dragonfly, Safari’s Web Inspector) is a very decent tool, pretty much everything you want is in there: Javascript console, ability to edit the DOM, etc.

Not so nice is the way AIR handles Javascript parse errors. It will just report an error without mentioning a line number or even a file. Surely they could have used a parser with better error messages, it is 2008, right?

Adobe AIR has the very nice feature that you can catch an event that is thrown when the network changes. This was exactly what we needed (or so we thought). Only problem is that an AIR application is pretty much shielded from the operating system. Of course that’s a pretty sensible thing to do, since it offers much more security for the end users (like they would be aware of that ;) ). For us this was a problem because there is no way to get the mac address of the router, which Plazes uses to automatically identify a Plaze.

We decided to continue using AIR because ‘plazing’ was not a top priority for us. Klinkr can run perfectly side-to-side with the Plazer and we mainly wanted a nice friend list. For the first release we built in an option that opens Plazes in the browser on network change. Not really a solution, but if you really hate the Plazer you can get rid of it.

We thought about two solutions to solve finding the mac address in a future version (still a low priority, though): the only way to interface with the operating system is through files or sockets, so an external program is needed to provide the mac address of the router. A simple cron job script that writes a file could do, but a tiny http server would be even better (because it would be up to date).

Plazes API

Initially we thought we would use the brand new Plazes API. Unfortunately, it was not (hopefully, yet) feature complete enough for our goals.

The main differences we spotted between the old and new API:

Features Plazes.net has but Plazes.com hasn’t

  • OAuth
  • Advanced Plaze queries (near, bounding box)
  • Choice of response format (XML, JSON, atom, iCal)

And the other way around, features Plazes.com has but Plazes.net hasn’t

  • Relationships
  • has_free_wifi field for Plazes
  • Stream of updates from friends

The relationships are actually hidden from the API docs, but can be found at http://plazes.com/relationships.xml. The stream of updates is only available as an atom feed.

Sooo, the main features we used Plazes for, finding out where our friends are and finding out if you can get free wifi before you go somewhere, seem to be disappearing from the API. Too bad.

For klinkr we initially thought of using both API’s, but since there is no point in using OAuth and still storing somebody’s password we refrained from that. We did start on implementing OAuth authentication, so when the new API becomes active for all users (and with relationships), we’ll do our best to port klinkr as fast as possible.

The way klinkr currently uses the API: it first pulls information about the authenticating user (/me.xml) and his/her relationships (/relationships.xml) to populate the friend list. For each friend it looks up the ‘closest’ activity (/users/{id}/activity.xml) to fill the list with. Then it polls the activities stream (/activities/related.atom) every 5 minutes to see if a user has a new activity. If so, it get’s the last activity of that user again (/users/{id}/activity.xml), because the activity stream doesn’t have all the information (like the address of a plaze).

Google Maps

Getting Google Maps to work was quite a challenge. Because the API isn’t really meant to be used from a desktop application we had to load it in an iframe and set up a ‘bridge’ to communicate with it. The iframe has to have to extra attributes ’sandboxRoot’ which contains the URL the API key is registered to, and ‘documentRoot’, which is the URI of the root of your application. Furthermore, the HTML file that contains the map, exposes a object with Javascript functions through an attribute (’childSandboxBridge’) of the window object. The set can be retrieved from the iframe by getting the element and then getting the attribute childSandboxBridge of contentWindow.

This means a you have to contstruct quite a big object of functions if you want to expose the complete Google Maps API, but fortunately, we only needed a couple of functions. It would be more sensible anyway to put most of your map logic inside the map HTML and only have a simple interface for the rest of the application.

Some remarks

Brightkite is another service that does a lot of things similar to Plazes. It doesn’t have an API yet (announced it though), else we certainly would have made a cross-service client (or at least, tried).

We would really like Plazes to make a more ‘general’ API so that users can play with it and come up with concepts that are less directly related to the philosophy of Plazes. Taking Twitter as an extreme example, it would be nice to be able to build ’services’ on top of Plazes.

On the other hand, that niche is probably filled by Yahoo’s Fireeagle, or will be filled when (if) they add historical data. The ‘unique’ feature of Plazes is that it’s a network: it knows who your friends are. It’s strange they don’t really seem to pay attention to that in the new API though. Let’s hope they are still busy figuring out how to make that part of the API really rock :)

Our code is licensed under GPL3 available at our Google Code page. Since it was mostly thrown together in a weekend by different people and without much coordination, it is pretty messy. If you want to check it out, you have been warned.


About this entry