This past Thursday I was privileged to speak at our local CocoaHeads about my history, and how I was able to bring my app to market. Since someone on Twitter asked for my slides, which don’t amount to much, I thought writing up my experiences would be a little more useful.
I didn’t grow up with computers. My first experiences programming were not when I was six on my Dad’s Apple II. We were poor, we lived on an Indian reservation in Montana, and for a good part of my life we lived in a mobile home. My first experience with a computer was in high school, after a semester of learning to type on an IBM Selectric, we moved on to one semester of computers, which was basically typing out documents in WordPerfect. That was it… for years. I didn’t start learning computers in depth until I had been in the Navy for a few years, and needed to learn them to make rank as a Radioman. It was then that I found I had a knack for technology, and started pursuing it. My first computer was a PC, a mistake I made exactly once. I had the machine for a few months before Linux was loaded on it for the first time. In 2000 I was introduced to Unix, and started working with OpenBSD, Linux, HP-UX, and Solaris. I enjoy Unix, I find that the system has a spartan elegance to it, especially the BSD flavors. Around this same time I heard that Apple was basing their new operating system, OS X, off of Unix, and I was anxious to try it out. In 2003, we moved back to the states, and I bought my first Mac, an iBook G4.
The iBook served me well, and I fell in love with the Mac and with the Mac community. I became a regular reader of Daring Fireball, and was inspired by a post named “The Life”. However, I had one college semester of programming experience in C, an experience that left a bad taste in my mouth, so I figured that “The Life” was out of my reach, put it behind me and moved on. Eventually I got out of the Navy and found work as a Unix sysadmin, using the skills that I learned while on active duty. The reality of work in a cubicle is much different than I imagined it would be. In the Navy there is always something different right around the corner. You will spend a max of 3–4 years at a single command, and during those years you will most likely have several different jobs. Things are much different as a civilian, and while I have a good job, the prospects of keeping this same job for the next ten or more years scares me more than a little. So, the question that came to mind was “is this what I want to do for the next 30 years?”, and Gruber’s article on The Life came back to mind.
So, I decided to learn Objective-C.
This decision was not taken lightly. I considered the possibility that it was beyond me, that I was not smart enough, or that I did not have the necessary math and programming and educational background to become a developer. Could I be dedicated enough to learn something so far out of my area? Was I smart enough to learn this? That last question gnawed at me, and I finally decided that there was no way I was going to know unless I tried, and gave it everything I had. So, I did some googling and found that for first timers wanting to learn Cocoa, most experienced developers pointed to what I now simply refer to as “The Book”, Cocoa Programming for Mac OS X.
For the next several months, I would wake up at 5AM and go through The Book, page by page, chapter by chapter, every challenge, no cheating. If I got stuck on something, I’d search the Apple developer documentation (which is excellent), or search through the CocoDev mailing list archives. I was investing in my future, so it was important to understand everything in The Book. Eventually, I finished The Book, and started working on my own little Mac app, a GUI version of a little shell script that I wrote called “go”.
The first few versions of Go were tough. I had a hard time getting my head wrapped around the “Modal, View, Controller” framework that Cocoa and the Mac developer tools are built around. I could not for the life of me figure out how to get an image to display in an NSTableView. That was by far the single most difficult hurdle I had to overcome. Changing my mindset from “Ok, place button here, and place image here”, which didn’t work, to “OK, place button here, and display data from my data source in this table”. I struggled for weeks, months even with this simple concept. Trying to work against the MVC is a sure way misery and failure. It was around this time that I found the local CocoaHeads group. I went to a meeting, and the speaker (a great guy), was talking about drawing pixels and getting your views to look just right. It was interesting, to be sure, but over my head at the time. I left that meeting disheartened, feeling that maybe it was simply too much for me, and I was just not smart enough.
I gave up, and for several months did not touch Xcode or Cocoa.
I’m not sure what brought me back, but I have a feeling it was stubbornness. The idea that there was a learned skill that I could not learn was too much for me. I started getting the feeling that I was almost there, that my understanding of Cocoa was incomplete, but I was just one more article read, one more blog post scanned, from finding the missing piece. So, I started reading again, I started building again, and piece by piece I started to understand Cocoa. I found that the best way for me to display an image was to use a value transformer. Store the data as a string, transform that string to an image, and the NSTableView would happily display that image for me. I started asking questions on Twitter and the mailing lists, and was recognized by Jim Turner, who ran CocoaHeads in Des Moines.
Jim is not the type of guy to give you an answer, but he is the type of guy to point you in the right direction. Jim and I exchanged emails a few times, and he pointed out where I was going about things wrong, or making things harder than they needed to be. Eventually, I built real, working versions of Go, which Jim was kind enough to beta test. Some of his critiques of Go were scathing, but absolutely necessary. Each email Jim would send me with a list of things that were wrong with Go, I’d drop into a to-do list and check off each item as it was fixed.
Some features that I worked on for months I killed. Some features that I spent months working on and hundreds of lines of code I found could be replaced with only a few lines of more functional code. The original version of Go used AppleScript and the Cocoa ScriptingBridge framework to launch the Terminal. I would build a shell script in Cocoa, then send that to the Terminal as a “Do Shell Script” AppleScript. This entire structure was replaced when I learned about the functionality of NSWorkspace and NSURL. Now, all bookmarks are URLs, and opened by NSWorkspace. Much simpler, and more functional. This discovery allowed me to take Go in a new direction, instead of being a launcher for SSH connections, Go could be a universal bookmarker, storing and launching bookmarks for anything that could be addressed by URL, which turns out to be just about everything. I finalized the functionality of Go, and spent another month or so building in a copy protection scheme and a 30 day trial, and… launched.
Farmdog Software was launched to the amazement of no one. I had the store open for three months and sold a grand total of seven copies of Go. I was languishing in obscurity. No one knew what Go was, who I was, or had heard of Farmdog Software. Then Apple announced the Mac App Store, and I knew that was my opportunity.
I started an entire redesign of Go, and renamed the application Go2. I redoubled my efforts. Now I was not only programming in the morning before work, but also at lunch, and at night after the kids were in bed. I built a custom NSCell class, and spent a long time building the Status Bar search menu that Go2 has now. Jim came to the rescue once again with a way to use the down arrow to navigate out of the search field, which was the final piece of the Go2 puzzle.
I submitted Go2 to the App Store, and in the last week of December it was rejected. Turns out there was an odd bug that only showed itself at launch time, and only on the first time the app was launched. I fixed that bug, resubmitted, and Go2 was in the store on day 1.
Go2 and Farmdog still have a long, long ways to go, but they are on their way, and that’s the important thing. If anyone can take anything away from all this I hope that it is to never give up. Never. Nothing worth doing is ever easy.