Chris' Blog.

My occasional thoughts on iOS development, developers careers, trying to make an income from the App Store, and updates on life in general.

Scalable Swift

Swift may be super-fast at runtime, but during compilation... well, it can be slow. Linkedin revealed in a blog post that they gave all their developers Mac Pros to get their compile times under control. I've experienced a project that takes 10mins each time you want to launch the simulator with 40KLOC. I had high hopes that Swift 3 would have an optimised compiler and solve this, however I found my compile times took around 30% longer after I migrated from 2 to 3. Also, after a codebase hits a certain size, the incremental compilation appears to give up, and any changes result in a full re-compile. And finally, code completion becomes unusably slow (or simply fails) after a certain codebase size too. Needless to say, these problems are disastrous to your productivity, so what can we do to solve them? Hopefully I can help you below.

Frameworks

My main recommendation is to split your app up into frameworks. Now I'm certainly not recommending creating your own cocoapods or carthage libraries or git submodules - I've done that before, it's way too much effort. However, with Xcode's nested projects, this solution can work with minimal ongoing maintenance.

The main architectural issue here is that you need to enforce careful separation of concerns, so that your code will split neatly into mostly-independent frameworks. Once you've done this, Xcode will only compile just the frameworks that have changed and your compile times + indexing + code completion should improve.

I recommend splitting your app up into frameworks like so:

  • Helpers: These are anything that needs to be used across the board, like currency formatting or styling or common views. This framework is the 'tip of the pyramid' when it comes to dependencies: it is to be used by all your other frameworks, but it cannot depend on anything else.
  • Services+Models: You may want to separate your model objects from your API services, but in my experience it's not worth bothering. These may rely on helpers.
  • Navigation: You'll probably have a custom home container controller and a bunch of helpers for various complicated navigation - I'd put them in here. This may also depend on helpers.
  • Many individual feature frameworks: This is where the magic happens: All your apps independent features, categorised into individual frameworks.
  • And: whatever else makes sense for your project.

How?

How do we make these frameworks? Here's the process for adding to a workspace. If you're using a project only, it may be slightly different:

  • Open your existing workspace.
  • File > New > Project
  • Select 'cocoa touch framework' because static libraries are objc-only (I assume this is because the ABI isn't stable yet).
  • For product name, use eg 'Helpers'
  • Team: none
  • Org name: MyCompany
  • Org identifier: whatever your normal bundle id is, with '.frameworks' appended, eg: com.mycompany.myapp.frameworks
  • Click 'next' and it'll ask where to place it with a save dialog.
  • Under 'add to', select your workspace. Under 'group', select the folder you want it to be nested under - folders have a yellow icon (eg skip the workspace and project levels).
  • De-select git - you want this subproject to be simply part of your normal git repo.
  • It should automatically choose the based on the group you chose, but double check and click 'create'.
  • In Xcode, you should now see 'Helpers.xcodeproj' nested under the group you chose.
  • Configure the deployment target at the project level to the same as your main project.
  • If you have extra configurations in the main project, add them to the subproject.
  • If you have per-configuration build settings for your main project, you may want to add these to your subproject.
  • Click on the main project, then for your target(s) do the following in the General tab:
  • Scroll to 'Embedded binaries' and add the framework MyApp/Foo.xcodeproj/Products/Foo.framework
  • Check it automatically got added to 'linked frameworks'. You may need to add it if its not there.
  • You can make frameworks rely on other frameworks, just don't make circular references. Eg the main app can use Helpers and Services, and Services can also use Helpers. But Helpers cannot then use Services.
  • When creating/moving code into your framework, you'll have to mark some classes and functions as 'public' to provide an interface to the main project.
  • You can use open instead of public if things have to be subclassable. I recommend using public where you can because it's like java's final, eg: no subclassing, which gives the compiler room for optimisations.
  • Anywhere you wish to use code from your framework, you'll need to have import Foo at the top of your swift file in the main/consumer project.
  • Share the scheme for the new project: Product > Scheme > Manage, then select 'shared' next to the project.
  • Celebrate!

Gotchas

There really aren't too many downsides to this approach, but some things to watch out for:

Xcode will recompile the frameworks if you change them automatically before recompiling the main module. But if it can't compile a framework, it might try compiling the main project against the last compiled version of the framework, and give a bunch of weird errors. So sometimes you should select the subproject's scheme and try building that first.

Sometimes have to turn off SWIFT_WHOLE_MODULE_OPTIMIZATION to get useful errors if builds are hanging.

Sometimes when you have compile errors, it's worth looking in the Cmd+8 tab to see the build output, in case it's an earlier error in one of the frameworks that is snowballing to further things.

To load images that are stored in the main project's xcassets from the subproject, you'll have to do this: UIImage(named: "X", in: Bundle(for: type(of: self)), compatibleWith: nil). Alternatively you can put assets in a bundle in the subproject which is tidy.

Update:

Apparently if you have an app with too many frameworks, you can increase your app's startup time. For instance, it is common to see 5s startup time on iOS9 with ~20 frameworks. As of iOS9.3 onwards, this problem is largely mitigated, and it is more common to see a 0.3s delay with a dozen frameworks. Apple recommends only having 6 or less frameworks in your app. I haven't done any tests, and I cannot say for sure if these techniques would be any slower than having one monstrously large app module. But this is something to keep in mind. You can read more here: useyourloaf.com/blog/slow-app-startup-times

One more thing

As of writing (Xcode 8.1) you can often get a significant compile speedup by adding the following user-defined build setting, it may be worth a try for you: SWIFT_WHOLE_MODULE_OPTIMIZATION = YES

Thanks for reading, I hope this helps!


Swift 3 Migration

Are you looking down the barrel of a necessary Swift 3 migration and groaning? Well, having recently reached the other side of that journey with a large codebase (40KLOC of Swift, excluding pods/carthage/etc), I found it to be difficult enough that it deserves a write-up, to hopefully spare the reader a landmine or two.

Xcode 8 and Swift 2.3

Firstly, you'll want to migrate to Swift 2.3. This is presented as an option when you open your project in Xcode 8 for the first time. Don't do what I did and migrate from 2.2 (Xcode 7) to 3 in one step - its simpler to take it in smaller steps.

2.3 will give you access to all the newest iOS10 APIs, and is as such a good stop-gap for now. Please note that Xcode 8.2 is the last to support 2.3 and after that, you'll need to migrate to Swift 3 syntax.

Xcode 8.0 is quite buggy - I recommend skipping it. In fact, as of writing, 8.1 just came out so this information is possibly redundant (sorry, this article took a while to write). 8.1 still has the overly-verbose logging issue which renders the simulator console almost unusable however - hopefully in 8.2 this will be resolved. However there are no longer blocking issues in 8.1 so I recommend using it.

Migrating

If you are part of a multiple-member team, I recommend getting one person's entire time set aside solely for a migration, in order to migrate as quickly as possible so that you don't have a nightmare of merge conflicts. I also recommend choosing a week when other team members aren't making large refactors/additions to the codebase too, again for the sake of merge conflicts.

Alright, jump in and run Xcode automatic migrator on your codebase. I recommend eyeballing all the migrations it makes - in my experience it did a poor job and many simple mistakes were made. This will take you quite a while unfortunately.

Once you've done this, try building your project. Don't be upset if you get many errors, this is simply a result of Xcode's migrator which isn't fantastic. I found that the error view in Xcode was often misleading regarding where the code wasn't compiling, and had to resort to the Xcode error logs (command+8) to find the true culprit of these problems. I recommend you do the same if you find any errors that don't make sense when looking at the code.

In the process of you fixing many errors, compiling, then finding more errors, and so on for many hours, you'll find that Xcode's indexing slows you down more than it helps. At this stage of the process, I found that disabling indexing really sped up the workflow. Run this from the terminal and restart Xcode:

defaults write com.apple.dt.XCode IDEIndexDisable 1

To re-enable later on, run the same command with 0 at the end.

Tests might not work upon first migrating - feel free to postpone solving this issue until after the main git merge to master has succeeded. The aim of the game is to get merged quickly to avoid conflicts with your other team members.

Dry run

If you have a really large codebase with many team members and are concerned about merge conflicts, you may want to consider doing a 'dry run' of the conversion to find parts that convert poorly. You can then refactor code such as this on your main (swift 2.3) branch of code such that it'll convert more easily when the time comes to jump in and do the full conversion. For instance, closures that have named arguments don't port across easily, and can be changed in the Swift 2 branch easily.

Another advantage of this technique is that when it comes time to do the full conversion, you can pull the latest from your master branch, then do the migration more quickly the second time around, and limit the length of time your Swift 3 branch exists for, thus minimising merge conflicts.

Pods / Carthage libraries

In the Swift 2.3 step in your migration, I recommend upgrading to the very-latest-but-prior-to-swift-3 version of all your dependencies/pods/carthage frameworks. Well managed open source projects, such as ReactiveCocoa, have subtle changes for the Swift 3 versions, and use of incompatible APIs in the prior version is marked as deprecated. Check all such warnings and migrate to the newest code style so that when you jump to the Swift 3 versions of such APIs, you will have fewer updates to make.

Also take stock of which libraries will need upgrading. Pure Objective-C frameworks will not need upgrading at all. For each of the Swift ones, check to see if there is a version for Swift 3 that has been released. If there hasn't been a Swift 3 version released, you have a few options:

  • Take the code out of the pod/carthage, and place it directly in your code, then migrate it alongside your own code.
  • Migrate to a different library that has the same purpose and also has a Swift 3 compatible version. I'd do this migration on your Swift 2 branch first, iron out the kinks, and merge that in before tackling the Swift 3 migration.
  • Rewrite your code so as to not use the library at all and remove it. If you're lucky, this might be a feasible option.

Time in lieu

You may consider letting one of your team members perform the final migration over a weekend to minimise merge conflicts, and allow them to take a couple days off in lieu the following week. Of course, do all you can to prepare for this ahead of time, such as migrating to 2.3 beforehand and preparing your strategy for your libraries.

Beware

In no particular order, some issues to be aware of (some of these may be resolved in Xcode 8.1):

Xcode 8 is buggy: communication between Xcode and the simulator are unreliable. Don't be concerned when this occurs, it's not just you.

Incremental compilation hasn't improved: usually you'll find that once your codebase gets to a certain size, it breaks down and any change will do a full recompile.

If you cast an NSObject to AnyObject via foo as? AnyObject, it returns a double-wrapped optional, so do foo as AnyObject instead.

var foo: NSObject? = nil; let bar = foo as AnyObject returns a non-optional AnyObject that is actually nil, causing runtime crashes.

Casting NSDictionary to AnyObject and back fails if you use as. Solution: Don't use NSDictionary anywhere, use [AnyHashable: Any] instead.

Any ObjC code that takes a NSDictionary will take a [AnyHashable: Any] from Swift. This will automatically bridge across from Int/Double/etc to NSNumber, String to NSString, etc. However any Swift-only types such as enums will also be happily passed across and cause runtime crashes. And the migrator will happily migrate some things attribute dictionaries across to using modern enums and trigger these issues.

UIControlState.Normal migrates to becomes UIControlState() often.

Swift 3 segfaults often - look in Report Navigator command+8 to find errors in code

Speed

Our biggest motivation for migrating from Swift 2 ASAP was our crippling compilation speed, and unfortunately compilation is still slow in Swift 3: on the latest rMBP15, it takes 7 mins for 40KLOC. However, there is a clever trick you can use:

Add the user-defined build setting SWIFT_WHOLE_MODULE_OPTIMIZATION = YES and magically our compiles are now down to 65s. This has been verified to work with other friends of mine with similar sized codebases. I have no idea if this takes precedence over the normal whole module optimisation setting, however it does seem to work.

One drawback I've noticed is that a subproject doesn't compile properly (if you have these), with SWIFT_WHOLE_MODULE_OPTIMIZATION enabled, the compile will simply never complete, as though it has gone into a while(true);. So if that happens to you, temporarily disable the build setting. It's unfortunate that we're at version 3 of the language and still having teething problems like these.

Hope this helps you get over the hump!


Enum-Driven View Controllers

Have you ever seen the term 'MVVM' (Model-View-ViewModel) and been intimidated by yet another acronym in our industry that you don't understand? In this article, I'll explain how you are very likely already doing MVVM, and you'll see how to tidy it up into a neat little state machine.

What you're probably doing

You're probably doing something like this in your view controllers. Nothing wrong with it, it's a good place to start:

class ProductListViewController: UIViewController {
    var isLoaded: Bool = false
    var isLoading: Bool = false
    var products: [Product]?
    var error: NSError?
    ...
}

See those four instance variables? Those are your ViewModel - see, you're doing MVVM already, without realising it - no big deal.

So here's a few stabs at a working definition of a ViewModel: It's the variables that drive what is being viewed. Or the model for what's happening in your views. As opposed to your real model, which has eg Products, Customers, Orders, etc.

Your VC is probably a state machine

A 'state machine' is one of those computer-science concepts that goes pretty deep. But for our purposes, all I mean is that your view controller has a limited set of possible states it can be in.

Here's a good analogy: It's very much like the gear selector in your car, you only have limited options: F, N, R, D (or 1..5+R if you love driving a manual!).

So what are the kind of states you're likely to see in a view controller:

  • Loading
  • Empty (loaded but there's no data, eg inbox zero!)
  • Loaded
  • Error
  • Not logged in (eg cannot load)

So lets bring the ViewModel and state machine concepts together into one nice package.

Enums to the rescue

Now if the above sounds like an Enum, you're right! So lets tidy up our original bunch of variables into an enum and a single state variable - emphasis on single:

class ProductListViewController: UIViewController {
    enum State {
        case Loading
        case Empty
        case Loaded([Product])
        case Error(NSError)
    }
    var state = State.Loading
    ...
}

One advantage here is that there is zero ambiguity about which state you're in. In the earlier example, it is possible for isLoaded and isLoading to both be true if you make a coding mistake, which is a confusing situation. But with an enum that is simply impossible.

Make the Enum drive the views

Next, I recommend using a didSet handler on the variable to update your UI. Eg:

var state = State.Loading {
    didSet {
        ... update views ...
    }
}

Now it's a simple matter of simply setting the value of the state variable whenever you want your UI to change. Eg your data fetching code will look as simple as the following:

func loadProducts() {
    state = .Loading
    ProductManager.sharedManager.requestProducts(success: { products in
        if products.count > 0 {
            self.state = .Loaded(products)
        } else {
            self.state = .Empty
        }
    }, failure: { error in
        self.state = .Error(error)
    })
}

To make the above example make more sense, here's some example code for the product manager:

struct Product {
    // ...
}

class ProductManager {
    static let sharedManager = ProductManager()
    func requestProducts(
            success success: [Product] -> (),
            failure: NSError -> ()) {
        // ...
    }
}

Table example

And for the sake of a half-fleshed-out example, here's something I commonly do: I have a view controller with a table view. For the loaded state, normal data rows show. For error state, one entire-screen-height cell shows with an error message. For empty state, one big cell with a helpful message shows. And for loading state, we have one big cell with an activity indicator. It all comes together beautifully as we'll go over now:

When setting the state, all that is required to update is to call the table's reloadData method:

var state = State.Loading {
    didSet {
        tableView?.reloadData()
    }
}

The table data source then looks like below. It is responsible for showing one special cell for the loading/empty/error states, as well as the typical product cells:

extension ProductsViewController: UITableViewDataSource {

    func tableView(tableView: UITableView,
            numberOfRowsInSection section: Int) -> Int {
        switch state {
        case .Loading, .Empty, .Error:
            return 1
        case .Loaded(let items):
            return items.count
        }
    }

    func tableView(tableView: UITableView,
            cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        switch state {
        case .Loading:
            return tableView.dequeueReusableCellWithIdentifier(LoadingCell.cellId, forIndexPath: indexPath)
        case .Error(let error):
            let cell = tableView.dequeueReusableCellWithIdentifier(CaptionCell.cellId, forIndexPath: indexPath) as! CaptionCell
            cell.caption.text = error.localizedDescription
            return cell
        case .Empty:
            let cell = tableView.dequeueReusableCellWithIdentifier(CaptionCell.cellId, forIndexPath: indexPath) as! CaptionCell
            cell.caption.text = "There are no products to view today, sorry!"
            return cell
        case .Loaded(let products):
            let product = products[indexPath.row]
            let cell = tableView.dequeueReusableCellWithIdentifier(ProductCell.cellId, forIndexPath: indexPath) as! ProductCell
            cell.textLabel?.text = product.name
            cell.detailTextLabel?.text = product.description
            return cell
        }
    }

}

And the table view delegate is responsible for making those special cells fill the whole screen:

extension ProductViewController: UITableViewDelegate {

    func tableView(tableView: UITableView,
            heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
        switch state {
        case .Loading, .Empty, .Error:
            return tableView.bounds.height
        case .Loaded:
            return tableView.rowHeight
        }
    }

}

And that's pretty much it for this post! Read on if you're curious about advanced enums.

Nested enums

A friend asked me to write about this one: An interesting technique you can use is nested enums. Now it can be a bit over-the-top, so use it judiciously, but here goes:

Say your state machine, when drawn out on paper, consists of maybe two 'top-level' states, but if you drill down there are more subtle states that are possible. Basically a hierarchy of states, like so:

Logged in
    Playing
    Paused
    Stopped
Logged out
    Registered
    Unregistered

You may want to consider nesting your enums like so:

enum UserState {
    case LoggedIn(LoggedInState)
    case LoggedOut(LoggedOutState)
}

enum LoggedInState {
    case Playing
    case Paused
    case Stopped
}

enum LoggedOutState {
    case Unregistered
    case Registered
}

var x = UserState.LoggedIn(.Playing)
var y = UserState.LoggedIn(.Stopped)
var z = UserState.LoggedOut(.Unregistered)

I'll leave this as an exercise to the reader.

Hope this has been helpful!


You can see older posts in the right panel, under 'archive'.

Archive

Scalable Swift 22 Nov 2016

Swift 3 Migration 6 Nov 2016

Enum-Driven View Controllers 3 Jan 2016

Status bar colours: Everything there is to know 30 Dec 2015

Android server 20 Dec 2015

Generating heightmap terrain with Swift 8 Nov 2015

Swift Education Screencasts 27 Oct 2015

Swift Image Cache 24 Sep 2015

Don't be slack 13 Sep 2015

Swift KVO alternative 23 Jul 2015

Swift Keychain wrapper 21 Jun 2015

Swift NSURLSession wrapper 12 Jun 2015

iOS8 View Controller transitioning bug 17 Apr 2015

IB Designable 18 Mar 2015

iOS App Architecture 2 Mar 2015

Video Course Launch 14 Feb 2015

Video Course Pre-launch 8 Feb 2015

Blogging Platforms 13 Jan 2015

Mobile in 2014 - Year in Review 11 Jan 2015

Secret Keys talk 16 Nov 2014

Dimmi 11 Nov 2014

Project setup in Xcode6 22 Oct 2014

Uploading to an S3 bucket from iOS 15 Oct 2014

iOS8 App Testing Roundup 28 Sep 2014

Storing obfuscated secret keys in your iOS app 16 Sep 2014

Getting Core Location / CLLocationManager to work on iOS8 14 Sep 2014

Accessing the response body in failure blocks with AFNetworking 2 10 Sep 2014

How to allow your UITextFields to scroll out of the way of the keyboard 8 Sep 2014

How to subclass UIButton in iOS7 and make a UIButtonTypeSystem 4 Sep 2014

New season 1 Aug 2014

House finished 17 Jun 2014

WebP decoding on iOS 9 Feb 2014

Moving on again 22 Jan 2014

Lossy images for retina iPads - JPEG vs WebP 30 Nov 2013

Career options I wish I knew about when I was younger 20 Oct 2013

Positivity and your friends 7 Oct 2013

Tactility 26 Jul 2013

WWDC-induced narcolepsy 15 Jul 2013

Back on rails 31 May 2013

Full circle 6 May 2013

Programmatic UI on iOS 3 May 2013

Screencasts and positivity 8 Apr 2013

Year of positivity 14 Mar 2013

iOS Dev State of the Union 6 Feb 2013

Adventures with IAPs 3 Feb 2013

No longer a Googler 23 Dec 2012

Localising iPhone apps with Microsoft Translator 8 Dec 2012

Fight back (app biz update 13) 12 Nov 2012

Sent to the backburner (app biz update 12) 25 Oct 2012

Lisi Schappi 7 Oct 2012

Today's happy plateau (app biz update 11) 26 Aug 2012

First week's sales of Today (app biz update 10) 19 Aug 2012

Today launch! And a difficult decision made... (app biz update 9) 15 Aug 2012

Approved! (app biz update 8) 5 Aug 2012

Creating a graph in Objective-C on the iPhone 3 Aug 2012

Hurry up and wait (app biz update 7) 30 Jul 2012

Today app marketing site 27 Jul 2012

Today app submitted 25 Jul 2012

UIAlertView input wrapper 24 Jul 2012

Mentoring 23 Jul 2012

This is too hard! (app biz update 6) 20 Jul 2012

Perspectives (app biz update 5) 9 Jul 2012

4th starting-my-own-biz update 1 Jul 2012

ScrumFox landing page 28 Jun 2012

Server Scope landing page 27 Jun 2012

Telstra Calls and Data Usage 26 Jun 2012

Service History + Dropbox 26 Jun 2012

Impromptu Presenter 26 Jun 2012

Fertility Tracker 26 Jun 2012

Baby Allergy Tracker 26 Jun 2012

Starting my own business, update 3 22 Jun 2012

Starting my own business, update 2 17 Jun 2012

Starting my own business - First update 10 Jun 2012

I must be crazy 6 Jun 2012

Finding your location on an iPhone 7 May 2012

A generous career 4 May 2012

Skeleton Key Cocoaheads presentation 3 May 2012

CHBgDropboxSync - Dropbox auto-sync for your iOS apps 1 May 2012

That book about that Steve Jobs guy 30 Apr 2012

Another app marketing idea 23 Apr 2012

Sweet grouped tables on the iPhone 17 Apr 2012

Skeleton Key App 11 Apr 2012

Another app marketing idea... 5 Apr 2012

Quickly check for any missing retina graphics in your project 3 Apr 2012

Skeleton Key Password Manager with Dropbox 2 Apr 2012

RC Boat motor finally mounted 2 Apr 2012

Promoting apps presentation slides 1 Apr 2012

How i just wasted a month on my latest app, and how you don't need to 26 Mar 2012

The Finishing Line 20 Mar 2012

Using Launchd to run a script every 5 mins on a Mac 20 Feb 2012

Generating AES256 keys from a password/passphrase in ObjC 20 Feb 2012

Indie iPhone app marketing, part 2 19 Feb 2012

My App Manifesto: Syncing + Dropbox + YAML = Awesome 15 Feb 2012

Indie iPhone App Marketing part 1 7 Feb 2012

Perspectives 2 Feb 2012

Accountability and Free Will 1 Feb 2012

Badassery 31 Jan 2012

Sacrifice 30 Jan 2012

Lead Yourself First 29 Jan 2012

How to ping a server in Objective-C / iPhone 26 Jan 2012

iOS Automated Builds with Xcode4 16 Jan 2012

Xcode 4 - Command line builds of iPhone apps 15 Jan 2012

Guest post by Jason McDougall 13 Jan 2012

Scouts, Games and Motivation 10 Jan 2012

2011 Re-cap 8 Jan 2012

Ruby script to increment a build number 4 Jan 2012

Turning 30? All ideas, no execution? 18 Dec 2011

CHDropboxSync - simply sync your iOS app's documents to Dropbox 14 Dec 2011

Deep-enumerating a directory on the iphone, getting file attributes as you go 10 Dec 2011

Getting a date without the time component in objective-c 6 Dec 2011

Memory management in Objective-C 4 Dec 2011

Starting small 29 Nov 2011

Dictionary Types Helper 29 Nov 2011

Observer Pattern in Objective-C 16 Nov 2011

Why you should give presentations 13 Nov 2011

How to get a programming or design job in Sydney 9 Nov 2011

Custom nav bar / toolbar backgrounds in iOS5 8 Nov 2011

Stuck 27 Oct 2011

Dead easy singletons in Obj-C 19 Oct 2011

JSON vs OCON (Objective-C Object Notation) 18 Oct 2011

In defence of Objective-C 16 Oct 2011

Update the MessagePack objective-c library to support packing 12 Oct 2011

Icons 11 Oct 2011

How to host a site on Amazon AWS S3, step-by-step 7 Oct 2011

Drawing a textured pattern over the default UINavigationBar 6 Oct 2011

Markdown Presentations 1 Oct 2011

More MegaComet testing: Ruling out keepalives 15 Sep 2011

MegaComet test #4 - This time with more kernel 14 Sep 2011

Building People 10 Sep 2011

Half way there: Getting MegaComet to 523,000 concurrent HTTP connections 5 Sep 2011

Making a progress bar in your iPhone UINavigationBar 22 Aug 2011

Hacker News Reader 20 Aug 2011

How to programmatically resize elements for landscape vs portrait in your iphone interface 16 Aug 2011

MegaComet testing part 2 3 Aug 2011

Australian Baby Colours 28 Jul 2011

Boat prop shaft 25 Jul 2011

Megacomet with 1 million queued messages 24 Jul 2011

Installed the strut and rudder 18 Jul 2011

Painted the inside of the boat 17 Jul 2011

Fuzzy iphone graphics when using an UIImageView set to UIViewContentModeCenter 13 Jul 2011

My 3 Data and Calls Usage 11 Jul 2011

Reading a line from the console in node.js 10 Jul 2011

Trim whitespaces on all text fields in a view controller 9 Jul 2011

Final finish 9 Jul 2011

MessagePack parser for Objective-C / iPhone 30 Jun 2011

Lacquering the starboard side 25 Jun 2011

What do do with EXC_ARM_DA_ALIGN on an iPhone app 23 Jun 2011

Lacquering the hull 23 Jun 2011

Staining the boat 22 Jun 2011

NSMutableSet with weak references in objective-c 20 Jun 2011

Iphone gesture recogniser that works for baby games 20 Jun 2011

Image manipulation pixel by pixel in objective C for the iphone 19 Jun 2011

Baby Allergy Tracker 12 Jun 2011

Power sanding the deck 10 Jun 2011

Planing the edge of the deck 2 Jun 2011

Figured out the deck 2 Jun 2011

Boat bulkheads 2 Jun 2011

Simulating iOS memory warnings 31 May 2011

Putting a UIButton in a UIToolbar 29 May 2011

How to allow closing a UIActionSheet by tapping outside it 29 May 2011

Finding the currently visible view in a UITabBarController 24 May 2011

Random Chef 17 May 2011

Centered UIButton in a navigation bar on the iphone 16 May 2011

Little Orchard 13 May 2011

Boat update 13 May 2011

How to get the current time in all time zones for the iphone / obj-c 12 May 2011

Design portfolio 10 May 2011

Tricks with grand central dispatch, such as objective-c's equivalent to setTimeout 9 May 2011

How to make an iphone view controller detect left or right swipes 5 May 2011

Centered section headers on a UITableView 5 May 2011

Christmas in may 4 May 2011

Finished trimming the boat (its floatable now!) and got some parts 29 Apr 2011

How to make a multiline label with dynamic text on the iphone and get the correct height 27 Apr 2011

Forcing an image size on the image in a table view cell on an iphone 20 Apr 2011

Git on the Mac 19 Apr 2011

Build a url query string in obj-c from a dictionary of params like jquery does 12 Apr 2011

Rendering a radial gradient on the iphone / objective-c 11 Apr 2011

Skinning the port side of the boat 8 Apr 2011

Skinning the side of the boat 5 Apr 2011

Sending a UDP broadcast packet in C / Objective-C 5 Apr 2011

How to talk to a unix socket / named pipe with python 4 Apr 2011

Skinning the bottom of the boat 31 Mar 2011

Service discovery using node.js and ssdp / universal plug n play 30 Mar 2011

Extremely simple python threading 29 Mar 2011

New rescue boat 26 Mar 2011

HttpContext vs HttpContextBase vs HttpContextWrapper 5 Nov 2010

Simple C# Wiki engine 30 Sep 2010

Simple way to throttle parts of your Asp.Net web app 29 Sep 2010

How to implement DES and Triple DES from scratch 4 Aug 2010

How to use sessions with Struts 2 30 Jul 2010

How to use Cookies in Struts 2 with ServletRequest and ServletResponse 30 Jul 2010

Using Quartz Scheduler in a Java web app (servlet) 27 Jul 2010

Javascript date picker that Doesn't Suck!(tm) 27 Jul 2010

Using Oracle XE with Hibernate 20 Jul 2010

A simple implementation of AES in Ruby from scratch 29 Jun 2010

Asp.Net Forms authentication to your own database 28 May 2010

AS2805 (like ISO8583) financial message parser in C# 7 May 2010

Ruby hex dumper 4 May 2010

Using Spring to manage Hibernate sessions in Struts2 (and other web frameworks) 13 Jan 2010

Emails in C#: Delivery and Read receipts / Attachments 12 Jan 2010

Using Java libraries in a C# app with IKVM 16 Dec 2009

Learning Java tutorial 27 Nov 2009

Using generic database providers with C# 17 Nov 2009

Scheduled task executable batch babysitter 29 Oct 2009

Working with query strings in Javascript using Prototype 30 Sep 2009

Still fighting with String.Format? 9 Sep 2009

How I'd build the next Google 24 Aug 2009

Getting IIS and Tomcat to play nicely with isapi_redirect 24 Aug 2009

Using the new ODP.Net to access Oracle from C# with simple deployment 11 Aug 2009

C# Cryptography - Encrypting a bunch of bytes 14 Jul 2009

Sorting enormous files using a C# external merge sort 10 Jul 2009

Reconciling/comparing huge data sets with C# 9 Jul 2009

Some keyboard-friendly DHTML tricks 10 Jun 2009

How to figure out what/who is connected to your SQL server 18 Mar 2009

Adding a column to a massive Sql server table 16 Mar 2009

Multithreading using Delegates in C# 10 Mar 2009

Using C# locks and threads to rip through a to-do list 6 Feb 2009

Using threads and lock in C# 3 Feb 2009

Compressing using the 7Zip LZMA algorithm in C# beats GZipStream 14 Jan 2009

MS Sql Server 2005 locking 17 Dec 2008

Simple Comet demo for Ruby on Rails 19 Nov 2008

Geocoding part 2 - Plotting postcodes onto a map of Australia with C# 24 Oct 2008

Using evolutionary algorithms to make a walkthrough for the light-bot game with C# 20 Oct 2008

How to tell when memory leaks are about to kill your Asp.Net application 16 Oct 2008

C# version of isxdigit - is a character a hex digit? 15 Sep 2008

Geocoding part 1 - Getting the longitude and latitude of all australian postcodes from google maps 26 Aug 2008

Converting HSV to RGB colour using C# 14 Aug 2008

Opening a TCP connection in C# with a custom timeout 11 Aug 2008

Oracle Explorer - a very simple C# open source Toad alternative 31 Jul 2008

Linking DigitalMars' D with a C library (Mongrel's HTTP parser) 23 Jun 2008

Connecting to Oracle from C# / Winforms / Asp.net without tnsnames.ora 16 Jun 2008

A simple server: DigitalMars' D + Libev 6 Jun 2008

Travelling from Rails 1 to Rails 2 9 Apr 2008

Online Rostering System 9 Apr 2008

DanceInforma 9 Apr 2008

Using RSS or Atom to keep an eye on your company's heartbeat 10 Nov 2007

Easy Integrated Active Directory Security in ASP.Net 24 Oct 2007