The indestructible unicorn, in development

Since the end or middle of July, I’ve been a part of this awesome team in Berlin, forging some beautiful user experiences for desktop and mobile, with Wunderlist and Wunderkit. The result of these experiences and the knowledge gained is an asset, alongside my time as a freelance mobile developer, which I want to share. This is the mission statement of a game changer for Titanium developers.

So, what do we, in my opinion, as a developer community need?

Well, let’s first look at what we’ve got. Appcelerator provides a free platform and since recently, also a marketplace for modules and templates, along with a few other similar services. The SDK is far from perfect and the documentation, although a work of constant improvement, is not up to shape. And we have the developer community, already creating components for their apps, but maybe not always generic enough for instant re-use. Finally, we have great resources of knowledge from web development, in best practices and useful patterns.

So what if we had a framework for building our generic components, and apps based on generic and custom components – with a unified syntax for Titanium developers all over? This framework would take the best patterns that we use for web development today and apply it to our mobile context. The language should be literal and the implementation must patch as much as Titanium’s shortcomings as possible, and document the missing pieces.

Adamantium.js 1.0 – “Unicorn”

What is happening right now: I am starting the Adamantium.js project over – turning a new leaf. From now on, the framework will be distributed as a module and made available in the Appcelerator open marketplace, and of course, source code on Github. Development of the four iterations that became version 0.1 was really a learning experience, along with the real life problems of working with complex applications the past months, and I am now aiming for a 1.0 release – production ready – hopefully before the year ends.

I am well into the full rewrite and after weeks of considering concepts, I feel ready to share my take on the best next step for Titanium developers – and my plan for reaching it.

For the purpose of not repeating myself, I will sometimes refer to this project as just AJS. And anyone who doesn’t know the origin of adamantium, should look it up.

The 1.0 release will be an iOS only release, but anyone with Android chops is more than welcome to join the team. As I mentioned, it will be distributed as a module, containing a full example application, which will also be made available in the AppStore. Both the framework api and the components used for the example app will have full test coverage, using a built in testing framework, with a public api for developers.

Module based klasses

First off, why did I call it Klass, and not Class? Since we’re adopting some patterns from web development, the class pattern for UI element style and configuration being one of them, we should try to separate two different things. The module klasses are easy to extend and instantitate, which makes creating custom and generic component modules more awesome than ever before.

$.Collection.extend('TasksCollection', {
	getCompleted: function () {
		return this.filter(function (task) {
			return task.completed;
		});
	}
});
var tasks = $.TasksCollection();
var completed = tasks.getCompleted();

The framework will provide a few basic application klasses for application controller, models, collections and UI elements, all of which are easy to extend for our generic or app-custom components. Internal navigation will be based on routes and everything from bootstrap to lazy-loading components and rendering UI will be done with optimized performance in mind.

$.Window.extend('MyWindow', {
	events: {
		"click #login": this.openWindow
	},
	initialize: function () {
		this.ready(this.loadWindow);
	},
	render: function () {
		this.leftNav($.CustomButton({ id: "login" }));
	},
	loadWindow: function () {
		this.subWindow = $.$OtherWindow();
	},
	openWindow: function () {
		this.subWindow.open();
	}
});

The syntax

From the success of jQuery, and other similar libraries, we get a chained syntax where queries can be made and objects be wrapped. What does that mean?

var el = $("Button:enabled").addClass("blue");

Adamantium.js will emulate the browser DOM and give you the same syntax as jQuery when interacting with elements. In fact, it’s the primary way of interacting with any instance of a klass in AJS, or at least a group of instances. UI elements can easily be grouped, filtered and manipulated. We will have full support of the same query selectors as jQuery, along with as much api parity as the context allows.

var rights = $.RightsCollection();
var wrongs = $.WrongsCollection();
var greyzones = $([rights, wrongs]).intersect();

The framework will also provide a wrapper for native objects, like strings and arrays. These enhanced object klasses are used internally to power AJS. Since we don’t want to manipulate an object we don’t own, we never touch the native objects directly. To enhance a string, you pass it to a framework function that returns an enhanced string klass instance – which also provides a chained syntax.

var words = $("Adamantium.js bends Titanium").words();
// => ["Adamantium.js", "bends", "Titanium"];
var shouts = $("Adamantium.js bends Titanium").words(function(word) { return word + "!"; });
// => ["Adamantium.js!", "bends!", "Titanium!"]
var code = $("Adamantium.js bends Titanium").reverse().lowercase();
// => "muinatit sdneb sj.muitnamada"

AJS provides a dynamic chain, where the klass instances in your query determines the the available action methods. And with the methods for sorting and manipulating itself in the model and collections klasses, we apply the same chaining syntax to all our AJS programming.

var tasks = $.TasksCollection();
var it = tasks.sort('prio', 'created').first();

Real short about the objects we use: Models and controllers are based on backbone’s implementation, but enhanced to optionally persist across sessions. Any subklass of a UI element you create, will be an Element klass instance – which some would call a controller or view controller. You can also subklass the base klass, to get a clean slate to start from.

On the horizon

So what happens after we have a production ready framework that simplifies development, increases developer happiness and productivity? On the roadmap we have handlebars templates, declarative UI, animation and callback queues, relational models and a lot of other cool stuff. Also, I hope to put effort into a 1.0 release for Android as well, sometime next year.

My plans for the future, apart from developing and maintaining AJS, includes lots of AJS tutorials and also development of some free and commercial components – as much as time allows.

Last words

Documentation is a part of Titanium development that has always been a problem, but in this project we provide abstracted klasses for native UI components, with unit tests generating documentation.

I’ve recently come into a lot of contact with Ruby on Rails, and I’m quite impressed with some of the patterns they use. AJS will promote “convention over configuration” and I envision this being our RoR equivalent, for Titanium Mobile development. The community needs a smarter way of doing things than the way Appcelerator currently provides.

If you feel like contributing in any way, speak up or fork the repo! Put your name on something awesome. And I appreciate any and all feedback in the comments.

  • Nikunj Sakhrelia

    I am in for the android and Iphone development of AJS 1.0