Filed under Articles

A list of top notch Git client applications for OSX.

I'm a big fan of Github and Git in general. I'm not afraid to use a command prompt for Git, but I'm also a bit lazy and like the convenience a GUI provides.

That's why I used to run Github for Mac to view changes, read commits and sync my local repositories with Github.

Github for Mac looks great, but last night I lost my faith.

Somehow the application decided to create a branch without me explicitly doing so. Furthermore it actually managed to screw up my entire code base by "auto" commiting changes using a message: GitHub for Mac: Throw-away commit.

Next thing I did was revert everything using the command line and dropping the Github app inside my trash bin!

Now I'm on the lookout for a new Git app for the Mac so I decided to create this list.

Tower

I've beta tested Tower almost a year ago and was impressed. The app looks great, it's stable and has pretty much everything you'd expect from a professional Git client including a built in diff tool. I do think the price is a bit steep at $36,75 (and that's with a 25% discount). It's also not available in the Mac AppStore (I do believe this is a downside).

Sprout

Sprout is a Git client available on the AppStore. It's currently priced at $19.99 making it a lot cheaper then Tower. It's also a lot more limited in functionality though. Sprout looks(feature wise) a lot more like the Github for Mac app, except it isn't that tied with Github. A trial is available on the developers website.

SourceTree

SourceTree is a free Mac app available on the Mac AppStore. It's almost as feature rich as Tower and supports both Git and Mercurial. The app isn't by far as slick as it's paid alternatives, and be honest, it feels a bit bloated. Perhaps bloated is a bit overstated, but the UI isn't intuitive or self explanatory.

Gitbox

Gitbix is also priced at $19.99 and available on the Mac AppStore. It's also a great looking app and offers a feature set comparable to Sprout. It probably has the most minimal UI of all apps, and some really well thought-out shortcuts and features. For example, Gitbox keeps track of any submodules you add and makes it a breeze to update them. A trial is also available on the developers website.

Conclusion

Mac OSX has a ton of great Git client apps. There is no easy choice.

All the apps above are build around their own workflow and mindset. I didn't get a chance yet to check out all the Git clients out there. For example: Gitti also looks very promising.

For the mean time I've decided to go with SourceTree and will probably purchase Tower or Gitbox in the long run.

If you are in need of a Git client all I can recommend is to download trials/ demos of all apps and find out what app fits your own workflow best.

Update: I'm running the Gitbox trial as we speak and I must say this app impressed me with it's stability and ease of use. Besides it makes working with submodules a lot easier. Ditching SourceTree...

— Written on the 29th of February 2012, filed under Articles.

Yesterday I found out another bug involving my "favorite" browser...

Internet Explorer 8, perhaps also 7, behaves a lot differently when doing a for in loop on a array compared to the modern browsers.

Basically the thing I wanted to do was dynamiclly fill an array with elements using a predefined order.

The resulting array would look a lot like this:

var names = [];
names[0] = "0. John";
names[1] = "1. Mary";
names[3] = "3. Jack";
names[4] = "4. Jane";

The thing is I couldn't control the order in which elements would be added to the array.

So the order in which elements would be added could easily look a lot like this:

var names = [];
names[3] = "3. Jack";
names[1] = "1. Mary";
names[4] = "4. Jack";
names[0] = "0. John";

Now here is the thing. Since you have blank keys in the array you can't use a regular for loop.

In the example above names[2] isn't defined which prevents you from creating a basic:

for(var i=0;i<names.length;i++){}

The easiest way to iterate through such a incomplete array is by using a for in loop like so:

for (var key in names) {

    var name = names[key];

    if (typeof(name) === "function") continue;

    document.write(name + '\r\n');
}

This however produces unexpected resuls in IE8.

In Chrome, Safari, Firefox and IE9 it would output:

0. John
1. Mary
3. Jack
4. Jane

In IE8 this produces:

3. Jack
1. Mary
4. Jane
0. John

As you might notice IE iterates through the elements of the array by the order in which they were added.

How to fix this unexpected behavior?

The simplest solution is to simply copy the array before iterating like so:

// IE fix
names = names.slice();

for (var key in names) {

    var name = names[key];

    if (typeof(name) === "function") continue;

    document.write(name + '\r\n');
}

This will reorder all array elements accordingly.

I've created a small snippet to see the bug and fix in action on jsfiddle.

— Written on the 24th of January 2012, filed under Articles.

I think iOS5 is a massive update for iOS App developers, read my reasons why.

Customizing UI components

I've done this a lot myself using hacks, tricks and quirks. With version 5 of the iOS SDK they've added customization to UI controls.

For example, you can assign a custom background image to a UIToolbar or UINavigationBarusing a simple background property. Before you literally had to jump through hoops to make this work.

Automatic reference counting (ARC)

iOS does not have Garbage collection . You know - a background process constantly checking to see if it can reclaim memory occupied by objects that are no longer in use.

Obj-c has a autorelease pool and retain release strategy, but nothing as fancy like the way Java and C# runtimes manage memory. Although the garbage collector makes life much easier for a developer, it also decreases efficiency on mobile devices.

Apple says they found a middle ground. Instead of having a separate proces recollecting memory, they have created a compile time solution. Using the static code analyzer - previously built into LLVM - they dynamically add alloc and release statements during compiling.

This will literally spare you of writing hundreds of lines of dull code. As an extra, Apple says it will also prevent common bugs like memory leaks and make writing code a lot easier.

ARC does require some code concessions, but Xcode 4.2 supports a tool that helps you update your existing code.

Storyboards

A sweet addition to interface builder. Instead of numerous interface files you can start dragging and editing all your views in one place. You can specify transitions between screens and the actions that trigger them. Perhaps more importantly, they also added a design pattern that can be implemented to send and receive data between controllers. Currently you'd have to implement protocols, delegates, notifications or some other custom way to maintain state between screens.

Also new to interface builder is creating UITableViewCell instances within XCode's integrated interface builder.

JSON API

Finally Apple turned their private JSON methods in a public API. Sure, there are great alternatives like SBJson , but adding third party libraries are always a burden when you'd consider something fundamental, like JSON, should be in the core framework.

Cloud Storage

New API's allow to easily store documents and key-value pairs in the iCloud. This makes it far easier to share data between multiple devices. Right now the most common used alternative is Dropbox . Dropbox has it's benefits, but I think iCloud should provide a more consistent user experience as well as a more consistent way to implement cloud storage.

Twitter

I really see this as a bonus. They've made it super easy to add share functionality inside your app. Too bad they didn't add Flickr as an alternative to share graphics with.

In the end I really think Apple addressed a lot of holes in the SDK. The points above are just scratching the surface - there are a lot of other major improvements that will for instance benefit game developers.

— Written on the 30th of June 2011, filed under Articles.

I've got a hunch Apple might buy Twitter in the near future.

The reason why I think such a takeover is believable has to do with the naming conventions used in the latest iOS SDK.

The SDK is full of Twitter API's wrapped inside Twitter.framework.

Why Twitter? Why not something more generic like Social.framework, Socialmessaging.framework or Socialupdates.framework?

Twitter is popular, but so is Facebook and other sharing services like Flickr and Instagram . It's true that Facebook and Apple aren't exactly on the same page , but relationships can change rapidly.

Apple is very picky upon naming conventions and coding guidelines within their public API. There are, for example, seldom changes to method names with new SDK versions. If there are any, they are always kept to a minimum.

While designing the API they must have considered making the Twitter API methods somewhat more generic. How would they add a Facebook status update option in the near future? Add an extra API specific to Facebook that, pretty much, does the same thing?

I believe Apple has specifically chosen Twitter to become an integral part of iOS. They deliberately choose to name it's social messaging framework Twitter.framework.

Now that last point is something Apple has a track record of - Integrating another companies software or service making it dependant. They know they want to stay independent. They've got burnt way too many times . Imagine what would happen if Twitter got bought by Microsoft or Google? They would loose the initiative and destiny off the functionality.

It's one of the main reasons Apple created Safari and the iWork suite in the past. To make it independant from IE and Office.

On the other hand Twitter is worth billions , but it still can't seem to generate a solid income (and Apple tried to launch it's own social network , but that clearly flopped ).

Both Apple and Twitter could seriously benifit from a takeover or increased collaberation between the two companies.

All of the above is of course just my take on the matter. Pure speculation and heavily biased. Who knows.. Apple might eventually not buy Twitter at all. Maybe they thought naming the API Twitter.framework was the best thing to do. They might have thought "premature optimization is the root of all evil" and add additional API's for other social networks along the way. We'll just have to wait and see.

— Written on the 29th of June 2011, filed under Articles.

iOS has some naming conventions that make it easier to load device specific resources like .png and .xib files.

Imagine having to wrap if statements around every line of code when loading resources just to check if the current device is the iPhone 4. With some easy naming conventions there luckily is no need to.

First there is the well known @2x suffix you can use to load high resolution images for the retina display.

Simply create low resolution versions of your graphics and give them an appropriate name like 'button_save.png'. Then create a high resolution version for the retina display and append @2x to the filename. For example '[email protected]'.

Note that I usually work the other way around and downsize retina graphics to a lower resolution version.

// Whenever you load an image using 
[UIImage imageNamed: "button_save.png"]; 

// or (iOS 4+)
[UIImage imageNamed: "button_save"]; 

// the iOS framework will automatically load the 'button_save.png', 
// or the @2x.png, depending on the device resolution.
// This works the same inside Interface Builder.This works easy enough for iPhone only app development, but what if you are also creating graphics for the iPad? There is a convention for that as well.

Simply give all iPhone graphics an ~iphone suffix and all iPad resources a ~ipad suffix without changing any code.

For example:

// The iPad only version of a graphic
button_save~ipad.png

// iPhone only version 
button_save~iphone.png

// iPhone only version (retina)
button_save~iphone@2x.png

iOS will automatically determine what image to load on a specific device with a specific resolution.

Images aren't the only resources that are specific to a device. Usually you will also require alternative interface files for the iPhone and iPad when you are for instance creating a universal app.

Multiple strategies can be followed, but when you have an almost 100% code share between an iPad and iPhone version, you can use the same method for NIB files as for images.

// The iPad only version the NIB file
MainView~ipad.xib

// iPhone only version
MainView~iphone.xib

As a final note. Don't forget to import all the image files into Xcode!

— Written on the 24th of January 2011, filed under Articles.

Tonight I’ve created my first painting. I haven’t painted for a long time, so it was quite a surprise to see how it would go.

For my first painting I’ve had an image inside my head of my girlfriend. I’m not really satisfied about the end result, although I’m not too ashamed to put it online.

Friends and family gave me a lot of painting tools and materials for my birthday last Saturday. A special thanks for Dennis, the brushes he and his wife bought me were superb!

From now on every Monday evening will be my evening to paint. If it’s not too much of a disaster I’ll post the end result on my blog.

— Written on the 22nd of March 2010, filed under Articles.

I know, it’s kind of stupid to post something about our first iPhone app three months after submitting it to the AppStore. During the development, and even afterwards, I didn’t have the time forgot to post about the app on my blog. The following days I’ll be catching up.

The Cooker is the first app Dennis and I created for the iPhone. Well, to be honest it’s not the first iPhone app we’ve built, but it’s the first one we published to the AppStore.

As it’s name implies the Cooker can be used during the preparation of food. It’s a handy tool to use when you’re for instance boiling potatoes. The timer is based upon seconds and easy to control using a special Time picker.

With this app we focussed on a few key features:

  • Easy to use

  • Fast and stable

  • Great look & feel

  • Different

  • Perfect fit for the iPhone

The Cooker looks rather simplistic and I think thats one of the greatest things about it. It's a single purpose, 'less is more' utility. Besides keeping the UI clean and focussed on the primary functionality, we’ve put some extra thought in the behavior of the application. To give you a few examples:

  • When pressing the Cooker during an alarm ring, the egg would instantly mute.

  • When leaving the Cooker and returning to it the timer would how much time was left on the timer. So when you for instance receive an SMS message, and leave the app to read it, the timer wouldn't be reset to 0.

  • When spinning the ‘advanced timer’ picker you’d notice that it would indicate 0 seconds and 1 second instead of ‘1 seconds’.

This simple ‘features’ might seem natural, but it’s the little things that set apart Apple and iPhone applications in regard to the competition.

Apart from it’s functionality the golden egg looks stunning if I say so myself :-)

Buy the Cooker for $1.99 at the AppStore

— Written on the 21st of March 2010, filed under Articles.

Hosting Rails apps on a Debian based Apache webserver isn't easy. Fortunately Passenger has made it a lot more gentle. This article explains how to install Ruby, Rails and Passenger on a Debian Etch machine running Apache 2.

Important is to define our "start of point". I'm not going to talk you through the installation process of Debian, MySQL or Apache. There are loads of tutorials out there that explain how to install those.

Now I mention it... if you don't know how to do this.. the following might be to complicated :-/

Back on topic. This is pretty much the software present before we start installing Ruby on Rails:

All packages were installed using apt-get (the stable releases).

Beside the required software, I've added a user called 'rubyrocks'. The Rails application has been placed inside the public_html of the user's home folder: /home/rubyrocks/public_html

Now we've determined our start of point, go log into your Debian machine and 'su' as root. Run the command:

apt-get install ruby rubygems

This installs both the Ruby runtime and the Ruby gems installer. Gems are Ruby's own 'apt packages'. There is a lot of discussion wheter you should use them or not. For now, I found it's the only 'stable' way to install Rails on my machine.

Next. In order to install passenger we require the following packages:

apt-get install build-essential apache2-prefork-dev

After those we can install the necessary Gems.

gem install rails
gem install rake
gem install passenger

If all goes well we've now successfully installed Ruby on Rails. In order to get Ruby hosted by Apache we've installed the Passenger gem.

To actually install/ enable passenger we need to run the following command: passenger-install-apache2-module

On my installation the passenger-install-apache2-module wasn't available.

This is due the fact ruby, rake and other commands are installed inside a gems directory, and not the /usr/bin.

I did the following to fix it:

# The first line will update the current $PATH
export PATH=/var/lib/gems/1.8/bin/:$PATH

# Create symlinks to the rake and rails command
ln -s /var/lib/gems/1.8/bin/rake /usr/bin/rake
ln -s /var/lib/gems/1.8/bin/rails /usr/bin/rails

passenger-install-apache2-module

Follow all the steps in the installer, and if necessary, fix any errors.

If all went well, Passenger is now installed. Time to create our first Rails app hosted by Apache!

The following is purely an example, but it should give you a good idea.

Start by creating a new site:

nano /etc/apache2/sites-available/rubyrocks

Put the following in the file:

<VirtualHost 192.168.1.2:80
        ServerAlias *.rubyrocks.test
         <a ="http://www.rubyrocks.test">www.rubyrocks.test</a>
        DocumentRoot /home/rubyrocks/public_html/public
        DirectoryIndex index.html index.rb
        RailsBaseURI /
</VirtualHost>

As you can see in the above example, I'm hosting my app inside the public_html folder of the user rubyrocks.

Apart from that, change the IP to your own..

Now we still have to enable the ruby runtime for apache. We'll do this by creating a .load file inside the available mods folder.

nano /etc/apache2/mods-available/ruby.load

And add the following

LoadModule passenger_module /var/lib/gems/1.8/gems/passenger-2.0.6/ext/apache2/mod_passenger.so
PassengerRoot /var/lib/gems/1.8/gems/passenger-2.0.6
PassengerRuby /usr/bin/ruby1.8

Save the file, and execute the following commands

a2ensite rubyrocks
a2enmod ruby
/etc/init.d/apache2 reload

Crossing our fingers here.... hopefully you won't get any errors :-)

If all went well you can now check your site at http://rubyrocks.test (if you get a 404, make sure your /etc/hosts file has the right line).

— Written on the 2nd of March 2009, filed under Articles.