Portfolio

A list of things I’ve done, and roughly when I did them.

2014

ImgurAnonymousAPIClient

There’s a lot of ways to represent an image in iOS. There’s the obvious UIImage, but then you have ALAsset, NSData. And images can be huge! so you don’t want to open them right up just to stream them through the network. I wanted to play around with all these image representations, so here’s a lame API client for Imgur’s anonymous API.

massy

I got a kitchen scale as a gift awhile back and I love it. But not many recipes are written with it in mind. Especially for baking, where something like “1 cup flour” has a wide range of potential masses depending on how you scoop out the flour. But manually converting all these recipes was a pain. So I thought, hey, let’s make a thing that scopes out all the ingredients in a copy-pasted recipe and switches any volumetric measurements to mass. massy supports like five ingredients, and even then only if you’re real careful about how you spell them, but I think the idea is worthwhile.

massy is live to the world, if you’re curious!

NWURLTemplate

URL templates seemed cool, and I had never done much with NSScanner before. I’ve never actually used URL templates anywhere. Like any solution looking for a problem, this was a complete waste of time.

YABrowserViewController

Nobody wants to be kicked out to MobileSafari just to open a quick link that scrolled by in some other app, so every app reimplements its own little shell around a web view. Except none of them are really quite what I want, and there’s no de facto standard that we can all rally around and get working nicely. So I made yet another one.

2013

HTMLReader

I guess my most successful open source project. HTMLReader parses HTML, and it does it like a browser, and it’s written in Objective-C. When I started it, all the ways you could parse HTML on iOS boiled down to libxml2, which is an excellent project with a terrible HTML parser. Working on Awful, we somewhat frequently came across markup that busted libxml2. For a while we could patch it up pretty easily in a preprocessing step, but at some point I said “enough” and looked around for a real HTML parser. I came up empty, and thus HTMLReader was born.

Shortly after starting HTMLReader, someone at Google came out with Gumbo, an HTML parser written in C. If they’d been just a couple months quicker, HTMLReader would not exist today. Oh well.

2012

Awful

I started contributing to Awful, an iOS browser for the Something Awful Forums. The website was horrendously annoying to use on an iPad or an iPhone, and I figured “somebody oughta do something”. Well, turns out somebody already had. A year later I took over development as the creator no longer had the time (or will), and I’ve been overcomplicating things ever since.

PeopleSearch

I’m visiting my uncle for a few days. He mentions how annoying it is that his iPhone only searches a few fields in his address book, so he can’t e.g. find someone by searching for the company they work for. Well, I know some iOS development, I can fix that! So I banged out Baby’s First Address Book App and hooked up the search field to every bit of data and metadata that the address book could store. I guess it was a pretty lame payment for eating his food and sleeping in his house.

I think iOS now does a better job searching its address book. I don’t really know, I never search my address book!

2011

Flibbertigibbet

I wanted Pictochat (from the Nintendo DS) for iOS. It was fun poking around with ZeroMQ and Bonjour (I guess now we’d use Multipeer Networking). What was really fun was having my sister run immediate QA for a couple hours on an iPad attached to my computer. “This is broken!” *fix* *build and run* “All better!”

I’ve long wanted to make an app that has an easter egg: if you press the right crazy key combination, menu items will be highlighted in turn and in time to the Daft Punk song “Technologic”.

I got as far as trying to find the location on screen of a nested menu item, then I gave up. But I learned that HIToolbox is a thing!

songregistry

Two good friends were getting married, and they wanted a way for people to submit songs to play at the wedding. That seemed like a great little project to learn some node.js and try out some CoffeeScript. In retrospect, like so many of these little projects, they just weren’t big enough to learn anything all that useful.

Ulti

Between jobs, I figured a lil stats tracker for ultimate frisbee was just the ticket. My goal: write Ulti in a month, stick it in the App Store, and earn enough to go to the movies. I ended up going to the movies… thrice! Thanks, world!

It’s actually still in the App Store, where it pulls in less than one purchase per month. One day I will have sufficient shame to pull it down. (Or, better yet, start on my dream ultimate frisbee stats tracker, with a time-travelling interface, multipeer networking, and crazy touch gestures.)

2010

clitunes

iTunes controllers are almost the Mac OS X “Hello, world!”. If you restrict yourself to the command line, the field narrows fast. If you want something fast (i.e. doesn’t use AppleScript), narrower still. And if you want incremental search, you’re out of luck. clitunes does your typical play, pause, next, but you can also search by artist or song title and page through the results as you go.

This was my first and hopefully last project using curses. Also this is a spectacularly unfunny name that I’m now ashamed of having chosen.

This tiny Safari extension was neither original nor full-featured. I just wanted something that would let me right-click a link and send its target to Instapaper. I found extensions that did this but also did fifty other things, and other extensions that did everything but. I’m probably the only person who ever used this extension, and that’s perfectly fine with me.

Twobudget

Spreadsheets will almost always work for a given task, but they’re almost never the best tool to use. Twobudget replaces a spreadsheet I maintained for a few years that simply tracks shared expenses for two people. If you pay for something that’s intended to be split (or paid for outright by the other person), enter it into the app. It’ll keep a running total of who owes what to whom to make everything even.

WindowMan

There are a few choices for OS X applications that move windows around when you press keys. What’s rare is one that’s free. I turned up exactly one such result and the hotkeys weren’t even customizable without diving into the app bundle. I found that I wasn’t alone in holding this corner of the market in low esteem, so it was time to re-implement the wheel.

WindowMan ended up being a good guide for how to decouple an app like this. There’s the preference pane to configure hotkeys, there’s a background daemon that monitors those hotkeys and performs the associated actions, and there’s a menu bar item that serves as a quick reference and access to the preferences. I also implemented a table cell that acted as a hotkey recorder, which in theory someone else might find useful on its own.

Check out WindowMan on its own page.

2009

Courses

Like many universities, mine made online class enrolment as painful as possible. There were at least three different websites involved, and moving data among them was nontrivial. You’d go to one site to figure out which courses were offered in a given term. Armed with this knowledge, you’d head somewhere completely different to see what sections were offered, who the profs were, and when the lectures were held. Once you’ve figured that out, it’s time to go to a third site to actually enrol yourself. And if you cocked everything up (or sometimes through no fault of your own) and there was a conflict, you’d have to make some round trips to the other sites to clear it up and pick something else.

Courses scraped all these various sites and threw them into the Django databrowse app so you could see it all at once. Imagine actually searching for classes you want and seeing, in that same place, when that class was offered this term. Astounding!

GrowlTicker

I used to use Growl a lot, but its claim to being “unobtrusive” gets old fast when you have many messages in a short time. Having noticed how wonderfully distracting the scrolling tickers are on cable news networks, I figured Growl needed one. I never polished this up enough to contribute back to the Growl project, but if I ever use Growl again I’ll be sure to finish this up.

Lines

Lines is an old-school puzzle game. I had an afternoon and threw together a JavaScript version. Lines is still online.

PI to IP.21 Migration Tester

I spent a summer at a power generation company working on migrating tons of data from an old system to a less old system. I guess they wanted an intern to do what was rather laborious and repetitive work. A spot of scripting to automate the tools they already had (and some tuning of said tools) turned into this migration tester, which gave me a lot of free time.

SuperJimbo

This is the only school project I’ve listed here. It’s the project that every student who takes CS 452 (Real-Time Programming) at the University of Waterloo completes (well, if they want to pass). Despite this lack of originality it’s the school project I’m most proud of. Starting essentially from scratch (I think we were given some busy-wait serial I/O functions to get started), a classmate and I worked to build a message-passing operating system and kernel. Its main purpose was to work a train controller on an HO-scale train layout. The real-time component comes from ensuring you’re working fast enough to get the trains to the right places, given whatever calculation you have to do and the temperamental nature of the train controller.

Pathfinding, collision avoidance, and implementing an interactive game all on top of a kernel that you wrote yourself, done entirely in C and ARM assembler. Talk about a shaky software stack. Yet there’s something special about the first time you get that little train engine to move.

UW Weather

The civil engineers at the University of Waterloo run a little weather station and helpfully make the data available online. Since the vast majority of my time in Kitchener-Waterloo is spent on or near campus, the typical weather report from the faraway airport was of little use. I wanted the weather from the UW weather station, and I wanted it in my menu bar, so here came UW Weather. (I kinda wish the source of their XML feed wasn’t useless. I shouldn’t need regular expressions on top of an XML parsing library just to pull out a temperature.)

UW Weather has its own page and is still used.

Wiimote

An unnecessary wheel invention, this time connecting a Wii Remote to Mac OS. I hadn’t done a thing with bluetooth before, though, and a Wii Remote was the handiest such device I found. Naturally there are other projects that perform much better and have much more compatibility, and you should use those.

2008

Acquire

Acquire is a fantastic board game. When I wanted to play it more than my friends did, I looked for an online version. I found NetAcquire, a windows application with no Mac version available. So I made one.

This was my first time using Objective-C and Cocoa. Combined with having to reverse-engineer much of the windows application’s protocol so my version could talk to it, there was a considerable learning curve on this project.

Acquire has a dedicated page.

In/Out

I came across a 37signals post about an in-house app they had called In/Out that indicated at a glance whether everyone in the shop was in or out and what they were doing that second. This was far superior to the setup we had in place at the small-business IT firm I was at (where I was employee five of five), so I replicated it. But nobody used it.

The key was to use the BlackBerries we all carried around. I set up a dedicated email account on the Exchange server and wrote a Python script to poll for new messages and update the sender’s In/Out status. It took seconds to grab your BlackBerry, compose a new message to inout@example.net, and type your new status in the subject line.

My phone was a lot quieter after getting that running.

Schoolstuff (Mac)

In school I loved an application called Schoolhouse. You threw in the assignments and tests you had in your courses, and it’d keep you in the know for due dates. Also cool was inputting your grades and the course grading scheme so you could track your course mark on a pretty graph.

Schoolhouse got busted in OS X 10.5 Leopard, and the developer had no desire to open source his work. I got tired of waiting for an update and started writing a new one as an intro to bindings and Core Data. I ran out of steam trying to scramble up that nearly vertical learning curve.

(As an aside, when Schoolhouse finally updated with Leopard support, I experienced a data loss bug within a day of using it, so I ran far away. I hope it’s great now, but I’m out.)

Schoolstuff (web)

I started making a web-based version of the above Mac client as an intro to Django. I got somewhere with it, then found another web app with way more polish and switched to it.

I’m not sure why schools don’t offer something similar as part of their ridiculous courseware stack. Though I’ve figured out that courseware isn’t written for the students using it.

TextTwistClone

Text Twist is an old shareware game where you have two minutes to figure out as many anagrams as you can of a scrambled six- or seven-letter word. If you find a full-length anagram, you continue to the next round with your score intact; otherwise you lose your score.

This seemed like a good excuse to team up with a buddy and learn how GUI apps are made in Java.

Not doing that again. Blech.

2006

where2

I got tired of answering the question “where are you going after high school?” in my senior year, and it came up frequently as people continually changed their minds, so a friend and I put together where2. On it, our classmates could put their name and what school they were going to, then everyone else could just look at the list instead of asking and forgetting yet again. We got past 100 users and starting implementing in-app messaging, but then high school was over and there wasn’t much point.

In retrospect this had a chance to grow well beyond our circle of friends and acquaintances. Today, some social network or another would probably fulfill this role.