I had always want to make an app ever since it was a thing, but always seemed to be too busy. Work, study or trying to get various businesses off the ground all meant I didn't have the head-space for design and coding.
That changed early in 2015 year when a conflagration of events meant I had a) a great idea with a genuine need, b) a bit of time, and c) the bloody-minded chutzpah to try something I hadn't ever done.
So I opened a browser and typed:
Fast forward through two months of late night development (plus another month of building a massive database of cafes) and I had Pilgrim Coffee in the app store! It was a little rough, and definitely a 'beta', but I was immensely proud.
Some common questions I was asked were
- 'Who built it for you?' Answer: Me.
- 'Wait, you coded it yourself?' Answer: Yep.
- 'How did you do that? Did you have a background as a coder?': Answer: It's a long story. Sort of, but it was like re-learning how to walk and finding out I now had nine legs.
So, with the web, none of that was relevant. Firstly I wasn't ever that great at coding — a classic engineer, hammering and gaffer-taping things together until they didn't crash too much. Then, I didn't touch coding again for more than a full decade. In the meantime, the entire world changed.
Here are some concepts that had flown by me:
- Object-Oriented Programming. This paradigm just started to become mainstream when I did my thesis. I begrudgingly half figured it out, and ignored all the theory around why OOP exists or how to do it elegantly.
- Web front-end and back-end technologies. I had made some web pages in 1998 to show pictures of my friends, just for fun. I wrote them in HTML. I completely missed developments that bring us the amazing web of today - things like CSS, JS/JQuery, AJAX and frameworks like Bootstrap. Don't even talk to me about CMS systems, PHP or server-side scripting. They say it's now impossible to know it all (the so-called 'myth of the full-stack programmer'), though I know many enjoy trying to get close.
- Functional programming. An entirely new paradigm (to me) that's was beautiful and mind-blowing. Higher order functions. Recursion as the status quo. Generics. It's all incredible and it breaks my brain.
If you don't know what the above are — rest assured that they're all major developments, and all fundamental to addressing the challenge I set myself: building an app.
The unmet need that sparked Pilgrim Coffee
Finding amazing coffee is a labour of love, but still labour.
Firstly, why build an app at all? It was simple — to address a need I had myself, and what turned out to be the need of quite a few people around me.
The need was simple: to help us find cool new specialty coffee places in foreign cities we travel to. Every time a coffee buff like me travels to a new place, we go through a similar process to find all the new specialty coffee spots. We look through blogs/listicles, filter out what's not good, check Reddit, check forums, add them to a list, make a map, and look at what's nearby on any day and then go to them one by one.
Finding amazing coffee is a labour of love, but still labour. Wouldn't it be simpler if the catalogue of information could be captured in an app? An app complete with location data, opening times and photography?
Obviously yes. And surprisingly, nothing out there quite fit the bill. Importantly, every coffee aficionado I mentioned to was quite excited about it and would wonder why there's nothing quite out there.
Other apps/sites fell short in important ways:
- Content: We go to blogs because of the pictures, descriptions and experienced opinions. Reviews help, but reviews can't be the ONLY content. If you read 'pretty good coffee but cronuts were average' 1,000 times, it doesn't tell you any more than the first time.
- Geographic focus: Most apps tend to be best in a certain geography (e.g. Yelp isn't in China, and Dianping is only any good IN China). It's hard for outsiders to know where the amazing coffee is in, for example, Chengdu. But it's there!
- Non-specificity: Most apps are not specific to coffee - even in Beanhunter, which is coffee-specific, you'll get reviewers saying 'my scrambled eggs were cold. Also I'm more of a tea drinker and the tea was just OK'. Reviews don't work for highly specific fields. A cafe that's pushing the envelope will occasionally serve a dud, and acknowledge it (and will say sorry, try this one, and also all this other free stuff). It's what happens when you are constantly experimenting. A coffee fan will appreciate this and happily give constructive feedback, whereas a regular customer may just ding a place.
- Review systems can be gamed: Cafes with good marketing will feature highly, and a new amazing spot will go unnoticed. Also, cafes with a lot of foot traffic will always seem to rank higher. So you get a curious phenomenon where the downtown spot with an attractive and efficient barista that just does flat whites very well will rank as one of the best cafes in the city, whereas the roaster that supplies them and has a full-on tasting bar and incredible kitchen but which is in the suburbs will be further down.
The solution? A content-driven approach, a dynamic guide for coffee lovers written and maintained by coffee lovers.
One thing I didn't really think about was the business model. I figured I'll build it, they'll come, and I'll figure that out later. Ultimately, while this may have worked, it was a lot longer of a process than i thought. More on that in a separate piece.
It's all about getting to a working product as quickly as possible, then iterating... My first version didn't even support commas.
Time is precious. I can't spend too long doing something, only to figure out nobody cares. So after getting started (downloading Xcode, buying an Apple developer license for $99 and figuring out how to configure everything), I decided to build what would be my first minimum viable product: just a map of cafes where I lived at the time (Hong Kong) with a location sensor.
Version 1: The Minimum Viable Product (MVP)
The first version I built was extremely simple. It's all about getting to a working product as quickly as possible, then iterating. The first version would display a map, download a CSV file (a list, separated by commas) from a server, and put pins on the map wherever the CSV said. Since it was a comma separated list, my first version didn't even support commas in the descriptions! It was just a bunch of pins. But that was pretty cool! Here it was:
There was a whole long process of trial-and-error development and experimentation that went into building this first version, and I could detail that out in another post, but basically, it was a lot of Googling.
New iOS programmers starting in Swift should learn to read Objective C. Read, not write.
Some major questions I had to answer for myself:
- What platform should I develop on — iOS or Android? There are many pros and cons. In summary, I coded for what I have and for what a large chunk of my friends had — iOS. Many suggest starting on iOS, and expanding to Android later (though you can obviously go either way). The main downside (to me) of iOS development is the beta/testing release pattern: it takes days to get approved in the App Store even just for testing. Android requires no approval - you just keep releasing and releasing new versions.
- What language should I use - Objective C or Swift*? I chose 'Swift', Apple's very new functional/object oriented language that's simply beautiful to read and write. I really like it. The downside of using it is that most examples of coding out there are in Objective C. However - I'd say for any new Swift programmer with no background in Objective C: Learn to read Objective C. Read, not write. It's totally transferable. With just a little practise, you'll be able to translate anything.
- What map system should I use - Google, Apple or another? This is an incredibly hard question! Google is awesome, but doesn't work in China. Apple is getting better, but address resolution is never as comprehensive as Google's. Mapbox, a new kid on the block, was really beautiful but lacks core functionality (for now). So - I chose Google first, then switched to Apple, then MapBox, then a different version of Mapbox and now am back at Apple. I suspect this isn't over.
I mucked around with version 1 for a while. I showed it to some people, and noticed they kept clicking on places I didn't expect them to. I realised major problem number 1: it needed more functions, and data. As I edited the data, I also realised it's incredibly annoying editing the data in text format. The data needed to be in a better format. Also, my Google maps didn't work in China. So, I made some changes.
The second version: A bit less minimal, a bit more viable
Version two relied on Google Docs as the database back-end. This was awesome!! I had a list of cities, and a list of cafes in other separate sheets. The app would download the lists straight from Google Docs, populate the data on maps and then show me.
I took this out on the road to test it and hit major problem 2: it was too slow. Google Docs isn't designed to be the back-end of a major app. It took up to 20 seconds to load some of the busier maps, like New York. Unacceptable. Oh, and I had forgotten that Google Docs doesn't work in China either. So I redesigned again. I asked my friends 'hey do you know a good and simple cloud-hosted database to use?' and got some great recommendations. So I decided to migrate to Parse.
Sadly, Parse shut down in 2016/17. The world said goodbye to one of the easiest-to-use and most flexible databases for app development.
The result was still what I'd call an MVP (minimum viable product, in case you've been skimming). It shows that it can be done, and that a useful product can be made. But it looked great, was stable and was really, really useful (including in China).
One thing I've learned is that an app I built is always going to be an MVP. It wouldn't have mattered how many features I added — it would always have stretched my ability to the maximum. Why would I release anything with MORE than what I consider to be necessary? In talking with other engineers, I often hear the same view expressed. Every business I come across has "dragons" — bits of legacy code from the founders. They can take years to be removed, and sometimes never are entirely!
What came next
Pilgrim Coffee grew quickly. I grew it to 5,000 active users in around six months.
The life changed. I became separated (now divorced) and left Hong Kong to take a job in San Francisco with Lyft.
During that period, my database provider, Parse, said it would shut down. I considered migrating to another platform. But it was just too much to handle. I was too lazy to confront my emotions on the matter, and they got in the way of me making Pilgrim Coffee into something truly great.
Those emotions were: fear of failure, fear of success, and not understanding the grind of growing an app-based business. Looking around me in 2019, nothing has filled its space properly, and I had the perfect platform for a content-driven marketing business that was never built.
So in early 2017, when Parse shut down for good, I wound it down.
To this day I wonder why I let it happen, but the important part is that I won't let that happen again.