Actiontastic Forks Self, Feels Lighter

I don’t know about you, but I sure miss seeing new versions of Actiontastic showing up on this blog every few weeks. If I had to guess, I would even say frequent releases were more exciting than my occasional dives into CloudKit and the vision for cross-platform synchronized data using only web technologies.

This isn’t to say that the work on CloudKit is unimportant but only to say that delivering working software has more immediate benefits to readers of this blog than status updates on a project that probably seems invisible to people who don’t follow me on GitHub. Further, the JavaScript portion of CloudKit is holding up several other exciting projects. So here’s what I’m going to do…

Actionatr Absorbs Open Source Actiontastic

Open source Actiontastic and Actionatr are the same thing, so from now on I will refer to the open source Actiontastic as Actionatr, because that’s exactly what it is. CloudKit is still its foundation. It is still being actively developed and already has some really cool features as a platform.

For example, a one-liner will generate a data model that has routes on it plus a matching JavaScript version that runs in a browser or inside Adobe AIR. (When Mozilla Prism gains HTML5 client database storage, things might change.) Another one-liner will publish an upgrade to all desktop clients and migrate data models to match the server models. This includes the offline SQLite models for AIR. It also has the beginnings of AMQP support so that RabbitMQ can push realtime updates to the browser.

None of this is going away. I have, however, realized that the project has such a large scope that Actiontastic 1.0 shouldn’t have to wait on it.

Actiontastic 1.0

Actiontastic 1.0 will still sync across desktop clients as planned, but it will not have a Windows or Linux version. Those will show up when Actionatr arrives. This will allow me to focus on the data/sync part of CloudKit minus the JavaScript/SSB part of it and execute more quickly. It is sort of a Pragmatic CloudKit that includes web tech on the server and Cocoa on the desktop. “Purist CloudKit” will not use Cocoa.

A New Way of Looking at Your Data

Here’s an annotated peek at some Actiontastic and Actionatr source code for the 1.0 releases. I don’t like Photoshop hype nor do I like showing a raw un-styled UI, so this is my attempt to show real working code and highlight some of the new features that it enables.

Code

1. All Actions View

Sometimes you just want to see everything on your list, regardless of what project or context contains the items.

2. Project List View

The new project list view shows all projects with their actions listed underneath in a tree-like view. Projects can also be marked as complete.

3. Tags Instead of Contexts

Tags are a great way to build a scalable user interface. By scalable, I mean an interface that grows with the user. Contexts are canonical to GTD but tags are more universally understood, not to mention expendable. If you don’t do full-on GTD, tags are easier to ignore than the imposing “Contexts” button in the toolbar of Actiontastic today. (As an aside, the toolbar is going away in favor of an iTunes-like source list.)

So, you can still have tags for contexts like “calls” or “errands” but you can also use them in a more free form manner as your personal system grows. Beyond this, there is no more “one context per action” rule; you can apply as many tags to an item as you desire. Tag collections are in the works too, for things like “important” and “calls” in a single click.

4. Time Travel

Go back in time to see what was completed on each day.

5. Trash

Just in case you delete something that you didn’t mean to delete, these apps now have a Trash Can, just like your desktop.

Getting to 1.0: Actiontastic, Actionatr, GWT and Automagic REST

Not knowing if I cover enough technical subjects here on the blog, I thought I should throw in even more nerdery detailing the path from Actiontastic 0.9.3 to Actiontastic 1.0 with its web sidekick, Actionatr. This was inspired by Wolf Rentzsch as well as a post from Ivan Moscoso on the Pathfinder blog, where he asks about alternatives to GWT-RPC (which we’ll get to in a moment). This post could also be titled “Why I Should Blog More Frequently, In Smaller Chunks.” My apologies.

Background

Actiontastic has remained stubbornly at 0.9.3 for months now while I have refused to release a 1.0 that isn’t a 1.0. Sure, it could have been released anyway as a commercial app before so many others joined the Mac/Getting Things Done niche, riding the wave of cash to a beach front house on some island in the tropics. (A second scenario would be selling just enough copies to require keeping a full time job while relegating all evenings and weekends to email support, but let’s favor optimism when daydreaming, shall we?)

Instead, I have stuck with the original vision of building something I believe is a requirement for productivity applications — ubiquity. It’s not okay to not have my lists with me when I’m running errands. It’s also not okay to not have my lists with me when I’m away from the Mac and need to make some calls. Paper printouts don’t sync and thus don’t solve the problem. Web apps don’t cut it on the BART (yet). iCal/PDA syncing also doesn’t hit the 100% mark for two-dimensional lists that are central to canonical GTD. That’s where the hybrid desktop/mobile/web app comes into play.

“Just ship it” is good advice, but that very idea hinges on defining the minimum requirement(s) for “it,” a 1.0 release. Setting the bar at “ubiquitous” has increased the challenge for this project while focusing it in many other areas. For example, there won’t be lots of widgets and configuration options inside of dozens of popups, sheets, and panels. Instead, Actiontastic will remain focused on the Next Action idea with its filter bars catering to this sort of work flow.

Actiontastic Filter Bar

Exploration

As I’ve mentioned before, there have been lots of technology prototypes assembled behind the scenes. These include:

  1. A basic Java web app, started more than a year before Actiontastic was first released.
  2. Hard wiring communication between blocks of code in Actiontastic to a web service built in Rails. (Not really a serious solution but good for exploration of the idea.)
  3. Building an app that ran in the browser as well as the desktop using Flex and AIR (using Cairngorm which was pretty nice).
  4. Building an app that ran in the browser as well as the destkop using JavaScript/CSS/HTML with AIR.
  5. Building an app that ran in my own Mac app container (a variant of WebKit Apps) that used a WebKit plugin to allow local SQLite storage via JavaScript/Objective-C bindings. This option used only JavaScript/CSS/HTML for the interface so would have also worked online as well as on other platforms. ExtJS with Jester and a RESTful Rails back end were helpful with this approach.
  6. Building method #5 above without the plugin, tying it more closely to the Mac platform with WebKit hooks.

All of the above failed. Here’s why, using the same numbering as above:

  1. This was during the age of Struts, Spring, and Hibernate. XML configuration pain and mapping the same things in every layer of the app wore thin and led to picking up my first Mac programming book, Cocoa Programming for Mac OS X, if only for a change of pace. This also led to Rails.
  2. As mentioned before, hard wiring interactions isn’t an elegant design and would have been a nightmare to maintain as the application progressed.
  3. Although a Flex app can be themed to look like a native Mac app, I found that basic text support was not built into Flex in a way that current Actiontastic users would expect. This also required implementing my own widgets for things like sheets. Further, integrating with native services on the Mac required lots of hackery including an Actionscript-to-Java bridge to a Java-to-Objective-C bridge that has been deprecated. I’ll pass.
  4. Scrollbars, plus some of the problems with option #3 above.
  5. The plugin seemed like the wrong way to go as Google Gears, once it regains its Safari compatibility, will solve this same problem. More on that later.
  6. Sadly, this is the one I hoped would work the most. I love the idea of using Web Standards to build interfaces that work on the desktop and in a browser. This one made it very far including a complete theming of ExtJS to mimic Leopard source lists, sortable tables, fluid layouts with dragable dividers, animation, and even HUD windows. This may still be the platform for Actiontastic 2.0, given enough compatibility progress in the browser world. In the end, juggling incompatibilities between browser versions, even the same browser (Safari 2 vs. Safari 3 Beta vs. Safari on Leopard before it shipped) made things grow ugly. If you see your app as “managing documents” or targeting a more web-native look and feel, this could still work, but when trying to mimic precise UI behavior from the desktop world, things are not so good. For the record, WebKit is my favorite JavaScript and CSS environment, but building a desktop-like web app that meets multi-browser expectations would require a team and a very robust architecture. This might include basic objects that could be extended for browser-specific quirks (rather than wedging in the ugly but common “if Gecko then…” kinds of hacks throughout the app). An architecture like this simply wouldn’t fit in the time line for 1.0. More on this browser-specific targeting in a moment, though.

This leads us to today, where the failures aren’t really failures. They have been excellent learning experiences and perfect excuses to explore some new technologies. Getting back to the title of the post, this is where GWT and REST come in.

Automagic REST

Months ago, I blogged about the possibility of a fast, compiled REST app that could be generated from a data model. Rails sort of hits in this direction minus the “fast, compiled” and “generated from a data model” part. This isn’t to be snarky either. The scaffold_resource generator in Rails (soon to be the default in 2.x) can do an impressive job of generating a REST service, but it lacks a few things out of the box that are offered more easily on the Java platform today.

For starters, Java-land seems to be heading in a better direction, thanks in part to competition from Rails. These days, if you want a REST service in a green field environment, you can just generate it from a data model. The anti-patterns encountered during failure #1 above are largely gone. This is due to a mix of technologies: Netbeans 6.0, Jersey/JSR-311, and JPA. Check out this tutorial, and there you have it, automagic REST that produces and consumes XML and/or JSON.

KloudKit

In the same blog post referenced above, I joked that REST was the new SQL. This is the tie-in to the Mac platform. If your Mac app uses Core Data, then it is following common ORM patterns. It retrieves, saves, updates, and deletes records, most likely from a SQLite database. These operations map exactly to those in a REST architecture — GET, PUT, POST, and DELETE. Naturally, this mapping means that a Mac app should be able to easily talk to a REST web service. This is where KloudKit comes in.

KloudKit is being assembled on top of OAuthConsumer so that it can do transparent authentication from a Mac app to its web companion. If you’ve ever published something from iMovie to YouTube or used a Flickr uploader, it’s sort of like that in the eyes of a user. With authentication out of the way, KloudKit can replicate actions taken on the Mac to the web. Right now, this implementation is forming as a framework that uses Core Data’s objectsDidChange notification, but I could see it also working as an extension to Wolf Rentzsch’s MOGenerator.

The MOGenerator option would have less invisible “magic” and could generate a rich data model to act as the seed for the generation of the REST app. All hooks would be exposed in the generated code, favoring a sort of “annotation over confusion” approach (with apologies to Michael Easter who seems to have been the first to coin this phrase).

Given a clear path for interface development on the Mac (Cocoa), storage (Core Data), authentication (OAuth), and communication with a RESTful web app (KloudKit), the browser interface to this RESTful hub is all that remains. This is where GWT shines.

GWT
The Google Web Toolkit brings these advantages to a browser interface:

  1. Java is compiled down to JavaScript, reducing the amount of context switching needed during development. I’m not bad at switching from HTML to JavaScript, to CSS, to Ruby, to SQL, to Objective-C, to graphic design, but it could be easier. A mostly Java and Objective-C mix would go a long way to delivering desktop, mobile, and web apps for most operating systems.
  2. Easy internationalization support.
  3. Optimized browser-specific versions of the same app delivered according to each client’s needs.
  4. Reduction of HTTP requests by merging all graphics into a single file. This file is delivered to the browser in one request. CSS tricks are used to display the pieces in the right spots.
  5. Debugging of JavaScript using an IDE while running in “hosted mode.”
  6. A large set of widgets, allowing appearance to be styled with CSS. There is even an add-on to integrate GWT with Ext.
  7. Unit test support.
  8. Google.

GWT’s native method of communicating with the server is called GWT-RPC and this is its weak link, in my opinion. Not that GWT-RPC isn’t fast or well integrated into the client-side JavaScript. It is. However, the current 1.4 version doesn’t handle Java 1.5+ code, meaning it doesn’t work with annotations, which rules out JPA. This can lead to EJB 2 flashbacks for those who have been there, as it requires an extra layer of Data Transfer Objects, mapping those DTOs to and from annotated objects using pseudo-annotations as GWT compiler hints, two interfaces for each service endpoint, etc.

Fortunately, GWT also includes a JSONParser and a RequestBuilder that can be crafted to work with a REST service. It may be even easier than this, however. GWT includes JSNI, a JavaScript Native Interface which allows it to interact with third party JavaScript libraries. Jester, mentioned above, supports asynchronous JSON to REST services and can be configured to use mappings outside of the default ActiveResource conventions. Tying these things together seems like a nice approach.

Conclusion and the 1.0 Architecture

To wrap this up, we have a desktop app (even mobile apps using JME, Android, or the iPhone SDK), transparently talking to a REST web service. A browser app, compiled down to a single page AJAX app talks to this same service. Given that GWT now supports Google Gears and Safari support is planned, it won’t be long before the pure HTML/CSS/JavaScript vision is possible on all platforms.

Developer Release: OAuth for Mac Apps

The Mac OAuth Formula

A few Sundays ago, I had the pleasure of attending my first DevHouse event. This one was SHDH20, located in Cupertino. The event was an impressive gathering of hackers and thinkers, all of whom seemed ready to share their ideas and code.

At 8:00 PM, there was an OAuth implementors meeting that saw lots interested individuals seated anywhere they could find space. It had a sort of “town meeting” feel to it and Chris Messina did a nice job of coordinating the conversation. I had been following the mailing list with interest and reading the spec, but this meeting clinched it — OAuth was the way to go for Actiontastic to Actionatr authorization and, in my humble opinion, the way to go for all kinds of apps — desktop and web — to interact in a responsible and friendly manner.

So…What is OAuth?

Others have summarized it better than I will here, but one nice description that has been offered is this: OAuth is a valet key for web apps.

Consider the use case that is common on social networks right now. “Would you like to import your contacts from Gmail so that SocialApp X can find them?” Sure! Just provide your password (the same one that allows anyone to send email in your name, or delete every message you have) to SocialApp X and everyone promises to play nice. SocialApp X, Inc. also promises to only deploy perfect code so no bug will ever effect your Gmail account either. Awesome. Maybe you can trust them, but you shouldn’t have to (as Adam Kalsey put it recently).

The better use case is that of OAuth. Let’s try the above again…“Would you like to import your contacts from Gmail so that SocialApp X can find them?” Sure! Click. This time Gmail asks you if you would like to grant read-only access to your contact list for SocialApp X. You agree, and SocialApp X never sees your password and can only access what you have permitted. You stay in control, and changing your Gmail password doesn’t mean running around to a dozen other sites and updating your profile.

OAuth and OpenID

One area where OAuth shines is for sites that use OpenID and interact with desktop apps. Actionatr is OpenID-only and the former question of “How does a desktop app like Actiontastic login to Actionatr using something that requires browser redirects?” is answered beautifully. No extra username and password required. No enable-then-copy-and-paste-an-API-key interactions are required either.

The Code

So today, I am releasing the first layer of Actiontastic in its open source form: the OAuthConsumer framework. The MIT-licensed Objective-C 2.0 code is in the OAuth svn repository along with implementations for other languages like Ruby, Perl (including Jifty!), Python, Java, PHP and C#. The intent is to drop the framework into an app that you are developing and use OAMutableURLRequest in place of the usual NSMutableURLRequest for web interactions. The framework takes care of the OAuth specifics regarding tokens, digest signatures, authorization headers, and even provides Keychain storage for credentials. This is layer one residing beneath the next open source slice, KloudKit.

If you’re the type to dive in and build a copy of the framework for yourself, please be aware that the OAuth spec is still in draft form and this framework should be considered pre-alpha. I will begin adding docs and caveats to the project site as an aid for early adopters.

Leopard Compatibility

The latest version of Actionatastic (0.9.3) and its Quicksilver plugin are ready for Leopard. I have been running them for months on my developer builds. If you are planning on standing in line tomorrow evening for a copy of the next big cat, Actiontastic will be ready for the upgrade.

There is a small cosmetic issue related to the info button in the upper right corner but it isn’t a show stopper by any means. Basically, the “i” is not properly centered and the button does not toggle on/off visually. This issue will be addressed in the next release. The Anti-Drawer that it controls still functions correctly.

For those of you who shared your upgrade plans, thank you! There is something special in store for you and I am working furiously to deliver it.