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.

Pragmatic Reactive Programming

After working extensively with ReactiveSwift (formerly known as ReactiveCocoa) and RxSwift for the last year and a half, hopefully I can shed some light on what works when it comes to getting down and dirty with real projects.

Some jargon to help get started, feel free to skip this:

  • Observable (RxSwift): this is a stream of values. It may or may not give you a value immediately on subscription, and it might or might not be hot or cold. It's a bit vague.
  • Signal (ReactiveSwift): This is a 'hot' stream of values. This means that subscription doesn't affect the stream. Imagine a car with the engine already running (hot) before you get in (subscribe).
  • SignalProducer (ReactiveSwift): This is a 'cold' stream. This means subscribing affects the stream. Typically this means that when you subscribe, it starts the thing that you're observing, e.g. a network request. Imagine a car with a cold engine that starts up when you get in.
  • Variable (both Rx and Reactive): A handy bridge between the reactive and imperative worlds. Basically it's a wrapper around a plain old variable, and lets all subscribers know whenever the variable changes. It also lets subscribers know of the current value immediately upon subscription. If you're overusing this, it may be considered a code smell. Having said that, pragmatically, you should use it judiciously to get things done - it's unrealistic to make your codebase 100% reactive when you're dealing with UIKit.
  • BehaviorSubject (Rx): RxSwift 4 will be deprecating Variable because they think it is a sop to imperative programming - you must use BehaviorSubject instead at some point going forwards.

Alright, let's jump right in!

Observables/Signals vs Variables

Oftentimes, when facing a problem to solve, the question will be: to create an Observable or Variable? The observable will be more pure-functional, which is laudable. And a variable introduces extra state, which is something we wish to minimise. Rather than having too much state, it is better to have a minimal 'source of truth' state, and pure-functional observables derived from said source of truth. This way, you cannot fall into the trap of updating, say, your user account in one class but forgetting to update it in another class.

State

To this end, I recommend taking a leaf out of Redux's book, and follow the philosophy of having a single source of truth. For instance, I recommend one app singleton named State, which in turn contains an instance of each category of state required, such as User for login/logout state. Since, by nature, state is required to be stored here, I recommend using a Variable. Accessing would then look like so: State.shared.user.state.

Example of state:

class State {
    static let shared = State()
    let user = UserState()
}

class UserState {
    let isLoggedIn = Variable<Bool>(false)
    let name = Variable<String?>(nil)
}

Alternatives proposed include having your individual state objects (such as UserState above) be individual singletons in their own right. However the approach in the example above has one advantage: it exposes a single convenient chokepoint at which you can substitute your mocks for testing: State.shared.

View Models

Many ViewControllers will do well to be backed by a view model. The view model is responsible for deriving a subset of the application's state in a way that is simpler to apply to the appropriate screen. For instance, say you have a screen where the current user state is to be displayed in the navigation bar title: the view model is responsible for combining the State.shared.user.isLoggedIn and the user.name variables into one title observable. I recommend that these view models be structs, and contain only observables that are derived from the state singletons' variables.

Example of a view model:

struct UserDetailsViewModel {
    let title: Observable<String> = Observable
        .combineLatest(
            State.shared.user.isLoggedIn,
            State.shared.user.name)
        .map({ (isLoggedIn, name) -> String in
            if isLoggedIn {
                return name
            } else {
                return "Logged out"
            }
        })
}

Wherever reasonable: Use Variable for a source of truth, and Observable/Signal for a derived truth. Where 'source of truth' means your state singleton, and 'derived truth' means your view models.

On the other hand: Sometimes it is simply unworkable to have only observables in your view models. Sometimes you just need the value 'now' rather than binding it and trusting that it will be there later. Sometimes it just isn't practical to refactor your app to be Rx the whole way through. In these cases, my team has agreed on a pragmatic compromise: your view model will create pure-functional observables for all its fields, and then bind that observable to a Variable, and expose the Variable. As part of this, you'll want to change to using a class, so variable state and disposal is easier to reason about. For example:

class UserDetailsViewModel {
    let title = Variable<String?>()
    let disposeBag = DisposeBag()

    init() {
     Observable
        .combineLatest(
            State.shared.user.isLoggedIn,
            State.shared.user.name)
        .map({...})
        .bind(to: title)
        .disposed(by: disposeBag)
    }
}

View Controllers

In your view controller, I recommend using bind to connect your view models to your fields. For instance:

class EditUserViewController: UIViewController {
    @IBOutlet var name: UITextField

    let disposeBag = DisposeBag()

    let viewModel: EditUserViewModel!

    override func viewDidLoad() {
        super.viewDidLoad()

        viewModel.name
            .bind(to: name.rx.text)
            .disposed(by: disposeBag)
    }
}

This will accomplish one direction of data flow: from the state model to the UI. For the reverse direction, e.g. when the user enters a new name and taps 'save', I recommend building a series of 'State Services' for persisting those back to the state singleton. Feel free to think of a better name than 'state service', by the way. For instance:

struct UserStateService {
    static func save(name: String) {
        State.shared.user.name.value = name
    }
}

This way, your state services are the only layer responsible for applying business logic and directly manipulating your state, keeping such code away from view controllers, which we'd like to keep as simple as possible:

extension EditUserViewController {
    func tapSave() {
        UserStateService.save(name.text)
    }
}

Closing thoughts

A grab-bag of ideas that I couldn't figure where to fit above:

  • Bind things wherever possible, don't use imperative code. For instance, subscribing to a view model and using onNext to update a field feels very imperative. Rather, bind the view model to your fields. You want the code to read like 'this is what I want it to do' rather than 'this is how I'd like it done'.
  • Use combineLatest upfront to grab everything you need for a given field in a view model, rather than referring to State.shared.foo.x in a map statement. Otherwise you run the risk that a change to X will not update your fields correctly.

Best of luck!


Gondola

There's a lot of hype currently around React Native, so I recently decided to sink a good amount of time into it to give it a shot, and report back with my impressions. Admittedly, these are only a week's worth of impressions so keep that in mind.

I spent a couple week's worth of evenings developing a prototype for an app a friend and I wanted to run by a few businesses, see if there was any interesting in a full build-out. Long story short, we got market validation that the idea wasn't what the industry wanted. But i did learn a lot about React Native in the meantime which I'll now share.

Potential

There seems to be a lot of potential with React Native. It is an extraction rather than a framework. DHH, of rails fame, made this distinction years ago: good frameworks are extracted from things that are required to work, because many people's paycheques/families/mortgages depend upon it. I'll clarify: I assume it's an extraction - we can't know Facebook's internal strategy specifically, but it certainly points that way (eg they use it for their Groups app and now the core Facebook app). My point here is that React Native is battle-hardened and production-ready, unlike say other write-once-deploy-on-ios-and-android frameworks which decidedly weren't.

Working with Swift at scale is an exercise in frustration common to many teams - see Uber. Xcode cannot index, and compiles blow out exponentially once you hit ~20KLOC, depending largely on if you have many small files or fewer large ones. So the opportunity to change properties and see updates in an iOS simulator and an Android simulator on your computer within seconds is compelling. I can confirm that this aspect of React Native is productive.

Don't be scared off because it's Javascript. JS has come a long way since the 90s - ES6 really shines, with elegant syntax for classes, inheritance, avoiding var hoisting, and so on. Take full advantage of all this, because RN uses Babel to transpile your newest-style JS into whatever is necessary for iOS and Android's runtimes.

And, in short: it's not, well, terrible. Most other cross-mobile-platform JS frameworks like Titanium / Sencha Touch / PhoneGap / Cordova / Ionic, well, are. I think it's on par with Xamarin in terms of production-readiness, however its live updates make React Native more productive.

Thoughts

Here's a grab-bag of perspectives gained from my two weeks, in no particular order:

  • Watch a lot of screencasts. There are a few at egghead.io. You'll notice that there are a few different styles for coding in RN, which appears to be a bit in flux. Hopefully this coalesces to one style in future.
  • Watch the Youtube videos by Tal Kol, Wix is really doing well with RN.
  • Check out Ignite and watch their Youtube videos. I think Ignite is like Rails scaffolding for RN, and pushes you in the direction of best practices - highly recommended.
  • FlexBox (their CSS-based layout alternative to AutoLayout) is a bit limited. You'll often have to wrap things in a (few) view(s) to get the layout you want.
  • The RN 'packager' is buggy, so get used to restarting it.
  • I've seen layouts acting buggy, things positioning where the code clearly shouldn't allow, at which point I close and re-open the packager/simulator. There seem to be some kinks here.
  • It's hard to find 'best practices' for some things, eg what do I do for a navigation controller? I find Wix or Ignite have great solutions for this particular case. It appears some things like this aren't 'batteries included' by Facebook so you often have to find a good library for things that really should be included.
  • Learn the differences between Props and State. Roughly: props are for things passed into your components; state is for things your component changes about itself.
  • Flexbox basic stuff here: facebook.github.io/react-native/docs/flexbox.html
  • Flexbox advanced stuff here: facebook.github.io/yoga/docs/flex-direction
  • TouchableHighlight must have only one child, but that child can have lots of children, so get used to grouping everything in a wrapper view.
  • Logging is simple: console.log('foo'), then in the iOS sim, do Menu > Debug > Open system log.
  • No type safety is hard to let go of after Swift: I sometimes call a prop 'isSelected' and in some places refer to it as 'selected' and get confused. Flow might help with this - I haven't tried. Also you can strong-ish-ly type your props like this: MyComponent.propTypes = { isSelected: React.PropTypes.bool, etc };
  • You have to update a datasource instead of another state property if you want a list to rerender - this got me stuck a few hours.
  • To make a button where the text dims on tap but the background stays the same, have a view (with background), containing a TouchableOpacity (no bg), containing a Text.
  • Many of the builtin components are iOS only eg the action sheet, so watch out for that. Wix provide cross-platform solutions for most of these.
  • When choosing components, choose the one with the most github stars, least github issues, and simplest example usage.
  • Don't use var anymore, use 'let' instead. (let is like swift's 'var'; const is like swift's 'let'; var is js-hoisting-madness)
  • There are lots of syntax changes re ES6 v ES5 vs classic JS to be aware of, eg use for of instead of for in.

Summary

I recommend at least becoming familiar with React Native. As our industry matures and rates begin to drop, I think it'll become increasingly compelling at job interviews to be able to say: I can deliver iOS and Android apps to the business for the price of one developer.

And here's the prototype that was the result of, say, 10 hours work:


Gondola

I have a bit of a tale to tell regarding a homegrown Plex alternative which I've been working on for a year or two...

So, for years now, I've had a plex server in the garage, which I've used to entertain my girls and solve the problems of:

  • My oh-so-well-behaved offspring scratching the hell out of every DVD we buy them.
  • My did-I-mention-they're-well-behaved offspring screaming blue murder as I inch my way through DVD menus to get the damn things to play.

So far, so good: plex has helped keep the screaming-for-blue-murder down to a dull roar for years now. However, there have been many niggling issues with it that have driven me to think 'could I do better?', such as:

  • It requires a decently powerful server...
  • Which means it has a noisy fan...
  • Which means it must go in the garage...
  • Which gets awfully hot in the australian summer...
  • So I walk in my garage most days and hear the server's fan going full-tilt and I freak out about it being a fire hazard.
  • And other issues: Often it just fails for whatever reason and needs a server reboot
  • New versions of the client ask me to sign up and in - I'm not doing that!
  • If you try to seek in most movies, it spins forever and probably fails (i've never waited more than a minute).
  • It doesn't simply figure things out if you drop new movies in, you need to remote into the server and kick off a re-scan.

So, armed with a trusty text editor, I mucked around with ffmpeg, and Go[lang], and so on, until I came up with Gondola, which I'm now releasing as an open-source project here:

splinter.com.au/gondola

Gondola is the full suite: A transcoding-ahead-of-time media server which works from a Raspberry Pi or a fanless laptop (I recommend the latter); a native client app for your Apple TV, iPhone, and iPad; and a web client which will work on any Android device. I've put a small price on the apps in the app store (due to the hassle of getting them approved!) but you can compile and install them yourselves if you like.

Hope you like it!


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

Archive

Pragmatic Reactive Programming 11 Oct 2017

React Native first impressions 7 Apr 2017

Gondola 26 Feb 2017

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