Namespace.js - simple namespaces in JavaScript

Written on

Namespace.js is an incredibly small, simple and fast JavaScript library which simplifies creating 'namespaces' in JavaScript.

Sometimes, developers want to organise their JavaScript modules into a 'custom namespace' so that they can reduce clutter in the global namespace, at the same time bringing some kind or organisational hierarchy to their code and modules.

One example is if you are modelling animals with JavaScript:

// Create a namespace called 'Animal.Mammal.Feline'
var Animal = window.Animal || {};
Animal.Mammal = window.Animal.Mammal || {};
Animal.Mammal.Feline = window.Animal.Mammal.Feline || {};

Animal.Mammal.Feline.Cat = {
    speak: function() {
        return 'Meow!';
    }
};

Animal.Mammal.Feline.Cat.speak(); // "Meow!"

That is all well and good, but to create the namespace "Animal.Mammal.Feline" we needed to write this ugly and repetative code:

var Animal = window.Animal || {};
Animal.Mammal = window.Animal.Mammal || {};
Animal.Mammal.Feline = window.Animal.Mammal.Feline || {};

Yuck!

The only thing namespace.js does is to allow you to replace that ugliness with something a little more readable and concise:

namespace('Animal.Mammal.Feline');

Just think of how quickly you can define namespaces for all of the different types of cats in the world in your next JavaScript web-app about cats:

namespace('Animal.Mammal.Feline.Cat.Tabby');
namespace('Animal.Mammal.Feline.Cat.Siamese');
namespace('Animal.Mammal.Feline.Cat.Persian');
namespace('Animal.Mammal.Feline.Cat.Oriental');

I have put namespace.js on GitHub for those who are interested in using it.


Wordout - a new iPhone word game

Written on

Wordout is a fast-paced multi-player word game for iOS that me and some friends recently put together. It is available in the App Store.

Below are some screenshots of the game. They show what the aim of the game is: to put together a "crossword" of valid words (both horizontally and vertically) in only 90 seconds given a random set of 13 letters.

An example game round in Wordout An example game round in Wordout

You gain points for the letters you use, and lose points for the letters you don't use (or words that aren't valid). A game can be with you and upto three other players, and each game has three rounds. The winner is the one with the highest points total after all three rounds.

We hope you enjoyed playing the game as much as we enjoyed making it :-)


New blog, new technologies

Written on

I have just finished building my new blog using HTML5 on the front end, and Node.js on the back end. It is hosted on heroku.

I previously used BlogEngine.NET, but wanted to write my own blog engine using some of the technologies I have been working with recently - technologies that I am passionate about and will be working with a lot more in the near future.

Writing my own blog engine from scratch using bleeding edge technologies was really fun, and I learned a lot along the way. Some of these things are discussed below.

git + heroku = win

If I have a new blog post or new functionality to my website, I constantly commit changes to my local git repository. When I am ready to "go live" I simply commit to my git repository, and then push my changes to heroku. Publishing new blog posts or new functionality is literally as simple as typing:

git push heroku

After those three little words, my changes are live. It is simple, fast and powerful.

HTML5

I tried to use semantic markup and make use of the new HTML5 tags where it made sense to use them. Every page on this website is valid HTML5.

HTML5 in Internet Explorer (IE)

My new blog works in most browsers, and most modern mobile phones. That took some effort. I mainly had problems in IE7 and IE8 due to the fact that I was using HTML5 which is not supported in those browsers. John Resig does a great job in explaining why HTML5 tags do not render well in IE7 and IE8: because those browsers don't apply CSS styles to tags they don't understand.

Luckily, there are workarounds. The most popular one seems to be HTML5 Shiv. It is a script that uses a technique where older versions of IE are tricked into rendering unknown tags by creating a DOM element with JavaScript.

The following JavaScript would trick IE7 and IE8 into correctly rendering a <header> tag:

<script type="text/javascript">
    document.createElement("header");
</script>

You can include the full HTML5 Shiv script inside a conditional comment, so that it is only included for versions of IE older than IE9:

<!--[if lt IE 9]>
    <script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->

CSS3 and Responsive Design

I also put some effort into making this website look pretty decent on a range of browsers, screen-sizes and devices. Using CSS3 media queries, you can specify certain CSS rules that should target specific classes of devices - based on screen size, for instance. If you are using a desktop browser right now, there is a HTML5 icon at the bottom of this page. If you are reading this from a mobile device, it will not be visible. The CSS3 code for this particular piece of adaptive rendering is shown below:

footer #html5 {
    float: right;
}
@media all and (max-width: 360px) {
    footer #html5 {
        display: none;
    }
}

The first CSS rule applies to all browsers - it pushes the icon to the right of the footer. The second rule is embedded within a CSS3 media query, which will only apply to devices with a maximum width of 360 pixels: for those devices, the icon is hidden. I have done similar things in other places across the site - including adjusting font sizes appropriately.

Old blog post redirects

I use a Node.js module called express for helping handle HTTP connections on the server side. With express, it is easy to handle a URL and send a response:

app.get("/foo", function(request, response) {
    res.send("Hello World");
});

I use express to permanently redirect my old blog post URL's to the new URL format I use. To stay search-engine-friendly, I redirect using the HTTP 301 status code: permanent redirect. Here is a sample of code similar to what I have running on the server to help me with redirects:

// www.alexyork.net/blog/post/hello-world.aspx
app.get("/blog/post/:urlFragment.aspx", function(request, response) {
    var urlFragment = request.params.urlFragment;
    var post = BlogPosts.getByUrlFragment(urlFragment);
    response.redirect(post.newUrl, 301);
});

HTML5 and the future

I have been in the web development game for over 10 years - but I have never been as excited about web development as I am today. With HTML5 and the umbrella of related technologies and API's that go with it, coupled with awesome modern browsers for both desktops and mobiles, the future of the web is brighter than ever.

But enough talking - let's get back to coding!


Creating Custom UITableViewCell's with MonoTouch - the correct way

Written on

When I want to create a custom UITableViewCell in a MonoTouch app, I have been using the approach outlined in Simon Guindon's custom UITableViewCell tutorial that he wrote in 2009. I used that method of creating custom cells in my NDC 2010 open-source MonoTouch iPhone app. Craig Dunn's blog is a gold-mine for MonoTouch samples - and he too uses the same approach for creating custom cells.

In fact, almost every MonoTouch sample I have seen on the Internet uses the same approach. It seems to have become the "standard" or "accepted" way of doing custom cells in MonoTouch apps.

For some time now, I have had a feeling that this approach was not optimal and was somehow "wrong". It is essentially a UIViewController wrapped around a cell - the cell's Tag property being used to lookup the cell from a Dictionary. From the samples I have seen (and used myself) the Tag usually comes from Environment.TickCount.

Several things have always struck me as strange with this approach:

  • Sometimes during cell creation, the OS is so fast that the Environment.TickCount is the same for two cells created in quick succession - meaning we get a duplicate key exception for our Dictionary key!
  • I'm not sure we are supposed to be using the cell's Tag property for this purpose.
  • The GetCell method returns a UITableViewCell. Why am I dealing with UIViewController's wrapped around cells?
  • Why do I have to manage my own Dictionary to handle cell reuse - isn't the whole point of the tableView.DequeueReusableCell() method that it handles that for us?

With these questions in the back of my mind, I have always been uneasy about this approach, but never spent much time on improving it.

Miguel de Icaza discusses UITableViewCell's in a blog post, but he doesn't go into detail about how to design the cell in Interface Builder and instantiate it from a XIB file.

One of his comments on that blog post got me thinking, when he said: "I have no idea why anyone would create UIViewControllers for each cell. [...] It seems that those doing it are doing it because that is an easy way of instantiating the cell from a UI created in Interface Builder. They should have instead created a UITableViewCell template in IB, not a UIViewController that contained a cell."

I think this is what he was talking about...

A new approach

Add a new file to your solution for your custom table cell: "iPhone View". Give it the name "MyCustomCell".

NOTE: You are not adding "iPhone View with Controller" here. We aren't going to be seeing any form of UIViewController again :-)

Delete the UIView it gives you by default. Add a UITableViewCell.

With your UITableViewCell selected, go to the Inspector window in Interface Builder, and on the Attributes tab, give your cell an ID in the "Identifier" box. The ID can be anything, but it is important because we will use it again later so that cells can be reused during scrolling.

In the same window, but on the Identity tab, you will see a text box for "class". There, give it the name of your custom cell's class: "MyCustomCell". MonoTouch will generate a partial class with this name when we save and exit Interface Builder, and we will create the other half of that partial class later.

Use Interface Builder to design your cell: you probably want to add some UILabel's and other UI components.

To access those labels programmatically, create outlets for them and connect the outlets to the labels. In the library window, make sure that you are creating the outlets on the class that you chose earlier - and not on anything else (this often catches beginners out - creating the outlets on the wrong object).

You are done with Interface Builder now - so save and quit.

In the MyCustomCell.xib.designer.cs file, MonoTouch will have generated a partial class of type MyCustomCell. Don't touch that code - it will be auto-generated each time you make changes in Interface Builder.

You can and should change the MyCustomCell.xib.cs file, though. Create the other half of that partial class:

public partial class MyCustomCell : UITableViewCell
{
}

Notice that we inherit from UITableViewCell here - not UIViewController. You need to add that inheritance in yourself, because it won't be done automatically for you.

Add two constructors (you will need them both):

public MyCustomCell() : base()
{
}

public MyCustomCell(IntPtr handle) : base(handle)
{
}

I also like to put the logic for binding data to the cell in here rather than exposing each label and other UI components publicly via C# properties. I think this hides the nitty-gritty details from the outside world, and is "better practise" in terms of encapsulation. So I would also add a method like this:

public void BindDataToCell(Product product)
{
    productNameLabel.Text = product.Name;
}

In this example, however, I won't be sending in an object from my model, such as "Product" - I will just send in a string, but you get the idea.

Now jump over to your UITableViewSource class, where you should have a method called GetCell(). It is here where you will usually find the ugliness of Environment.TickCounts, UIViewControllers needlessly wrapped around cells, and Dictionaries hanging on to the cell UIViewControllers. But this time, we will not need any Dictionaries or UIViewControllers. Instead, we will use this code:

public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
{
    var cell = tableView.DequeueReusableCell("CellID") as MyCustomCell;
    
    if (cell == null)
    {
        cell = new MyCustomCell();
        var views = NSBundle.MainBundle.LoadNib("MyCustomCell", cell, null);
        cell = Runtime.GetNSObject( views.ValueAt(0) ) as MyCustomCell;
    }
    
    cell.BindDataToCell("You are on row " + indexPath.Row);
    
    return cell;
}

You will need this to make it compile:

using MonoTouch.ObjCRuntime;

A simple TableCellFactory

You wouldn't really want to copy and paste that code in every UITableViewSource you have throughout your app - because that would give us lots of code duplication. To avoid that, and add a little bit of elegance the code, I have taken the liberty to create a tiny, light-weight and generically-typed factory class which will take care of this cell-reuse and XIB-loading business for you:

public class TableCellFactory<T> where T : UITableViewCell
{
    private string cellId;
    private string nibName;
    
    public TableCellFactory(string cellId, string nibName)
    {
        this.cellId = cellId;
        this.nibName = nibName;
    }
    
    public T GetCell(UITableView tableView)
    {
        var cell = tableView.DequeueReusableCell(cellId) as T;
            
        if (cell == null)
        {
            cell = Activator.CreateInstance<T>();
            var views = NSBundle.MainBundle.LoadNib(nibName, cell, null);
            cell = Runtime.GetNSObject( views.ValueAt(0) ) as T;
        }
        
        return cell;
    }
}

If you put that somewhere in your iPhone app, you can reduce your GetCell() method to this:

public class MyTableSource : UITableViewSource
{
    private TableCellFactory<MyCustomCell> factory = new TableCellFactory<MyCustomCell>("CellID", "MyCustomCell");
    
    public override UITableViewCell GetCell(UITableView tableView, NSIndexPath indexPath)
    {
        var cell = factory.GetCell(tableView);
        cell.BindDataToCell("some data");
                
        return cell;
    }
}

I have a fully-working sample over on github, called MonoTouch.CustomTableCells.

These links also helped me out out:

I would appreciate feedback and discussion, and any improvements or tips, so please leave a comment if you have anything to add. Good luck!