How I used Swift to turn this site into an app in six weeks
An update for Hacker News
A couple of years ago I turned an out-of-print book into a website and my story of doing that was well received on Hacker News. That wasn’t particularly tough for me - I’ve been building websites for 15 years. But I wanted to make an iOS app version of the site and this is the story of how I went from zero iOS/Xcode programming knowledge to having an app on sale in the App Store in six weeks.
Just to give an overview of progress since my last update two years ago, last month the site had 122,000 unique visitors. Traffic has roughly tripled year on year. The graph below is of sessions.
The rationale behind an app
Last summer I decided that having a paid-for app version of How a Car Works might be a good way to monetise the site, without plonking more adverts in front of people. I already had a handful of people each week buying a PDF version of the website through Stripe for $5. This was surprising to me as I’d consider the friction too high, and certainly didn’t think that a PDF had enough advantages over the free HTML to make it worth the trouble of fishing out a credit card and typing in the details.
An app is a low-friction way for people to support the site, get rid of adverts, and enjoy a more polished and quicker experience. I think that’s a good deal for both parties, and I’ve kicked things off at $0.99 which I hope will remove price from the equation for buyers.
Anyway, I thought an app was needed, and it looked a promising project for me to explore native apps for the first time... I did nothing for four months.
I should say at the outset that I wouldn’t have even considered making this app if I didn’t already have an audience from the HACW site. Last month I had 19,500 visitors on iPhone, and 9,000 on iPad. (Desktop usage is now 47%, mobile 44% and tablet 9%). That is my market - without that base I’d be launching into a void and competing against hundreds of other apps.
iOS first (and maybe only)
I built for iOS first because:
- Virtually all my tablet traffic is iPad.
- Half my mobile traffic is iPhone.
- iPhone has 15x the traffic of the most popular Android device (Samsung Galaxy S5).
- The image below shows the fragmentation.
- I already own iOS devices. My network of tech-savvy friends are almost all on iOS so they can help me test. I’ve never bought anything on Android despite owning a secondary phone and tablet.
If it sells well on iOS then I’ll certainly build for Android as well, but if it doesn’t sell then I think it would have been even less successful on Android.
Adventures with Rubymotion
I’ve been coding Ruby for three years now. I’m (probably too) comfortable with it. I had made a couple of abortive attempts at learning Objective-C over the past few years without getting much past “Hello, world!” and I didn’t fancy another repeat of that. Plus the square brackets and malloc calls hurt my head - I never learned C.
Rubymotion looked polished and like it would fit the bill. I bought a licence for $199 and worked my way through Clay Allsopp’s Rubymotion Tutorial. It wasn’t too tough to pick up, and it was satisfying to see stuff working on the simulator. I adapted the code from the tutorial and built a simple app that used CoreData hammered into the shape of ActiveRecord by a Gem called CDQ. I dumped the site to JSON and image files, imported this into CoreData, and used UIWebView to display the articles. It all worked quite neatly. Even through the abstractions of Rubymotion I saw the speed, utility and power of Cocoa components like UISearchBar and UITableView. Things that scar(r)ed me when I first tackled Objective-C didn’t look so strange now.
The Rubymotion rejection
I registered as a developer with Apple, finished the app in Rubymotion. Less than two weeks after I started learning Rubymotion, I submitted to the App Store on 28 November.
This first app was rejected ten days later for being too simple and lacking sufficient interactivity - the reviewer thought it should be on the iBooks store. Faced with having to add shiny interactivity and animation, which is where Rubymotion became really tough, I stewed on my options for a few weeks.
I’d read a bit about Swift when it launched. General opinion seemed to be (and still is) that it’s not production ready. Advice on whether to learn Objective-C or Swift for new entrants came down on the Objective-C side. But I worked through the first couple of chapters of Beginning iOS 8 Programming with Swift by Simon Ng.
Everything just worked nicely. The syntax of Swift made sense. Optionals were a bit mysterious for basically the entirety of the book but apart. Using Xcode took me straight back to when I was 15 and playing around with Visual Basic 6.
By the end of this book I was able to recreate the original Rubymotion app using Swift in about three days. Everything about the experience was much more polished and efficient. From being able to switch simulated devices at the click of a button (Rubymotion uses rake tasks and the command line), to code completion and documentation.
With just some basic Swift knowledge it’s actually quite easy to understand and re-write Objective-C examples in Swift. This meant I could use the depths of Stack Overflow to help me solve problems (and I did, going way back 2009 for solutions to some stuff). One of the reasons not to learn Swift was that existing examples, tutorials and libraries are obviously all for Objective-C - I can say this is definitely not an issue for beginners.
Another frequent complaint that I see is that Xcode is buggy with Swift. Sourcekit would stop autocompleting for a few minutes a couple of times a day. It usually just fixed itself. Xcode crashed completely just once in two weeks of using it. It’s no more buggy than I’ve found almost anything else to be.
My only difficulty in getting the app finished was with using UISplitViewController to manage a Master-Detail layout that worked universally on both iPhone and iPad. That took me about three days of fiddling, but the end result is a single code-base and storyboard for the whole app. I submitted my second version on January 26 and it was approved :) on 3 February.
So, that’s my story. Here are my thoughts looking back:
I don’t want to knock Rubymotion too much because it’s a well-documented product which did exactly what it promised to do. I feel like I had value out of the $199 I paid for it, even though I never used it in production. But with Swift on the scene I feel the landscape has changed and Rubymotion doesn’t really make sense for any use case that I can think of.
Having been through the process back-to-back with both Rubymotion and Swift/Xcode I would say do not use Rubymotion. Don’t make the mistake of thinking that it’s quicker to use your skill and experience in Ruby and your existing workflow than to learn to use the tools as they were intended. The closest comparison I can come up with is writing code in MS Word because you know your way around it. It’s madness.
Lacking the Xcode UI and doing everything through code made everything much harder, slower and more complicated than it needed to be. My Rubymotion app looked completely bland because I had no idea what was customisable and what wasn’t - everything had to be done in code. Xcode presents a neat view of properties for all your UI elements - you can see at a glance most of the stuff you can change. And you can see the results immediately. For a beginner it’s more intuitive to play around with, which is exactly what you need to do. This is a huge deal - if you’re starting out on iOS you need to see what your options are, and feel happy playing around. You must use Xcode.
You must use autolayout. This is so important that, despite it being added complexity in an already intensive course, Paul Hegarty covered it in the second lecture of his course. With the iPhone 6 and 6 Plus on the scene it’s going to be very, very hard to cover all screen-sizes with Rubymotion.
My Rubymotion attempt was iPhone only. I was happy with this at the start “My Ruby prowess will see me have this finished much quicker, if it works I can build an iPad version.” As soon as I switched to Swift I saw that it was almost zero extra effort to make this a universal app and almost double my potential audience.
The third biggest downside of Rubymotion is being an outcast. You’re going to pay for a developer account but you can’t use any of the brilliant resources that are available to you. Years worth of WWDC videos that you can watch in the bath which discuss all the iOS features that have you mystified as they are unveilled and utilised. For example, there are five detailed talks on Autolayout that you can watch in the bath. But using Rubymotion you’ll be scrabbling around on Youtube for even one 360p video that’s probably out of date.
Other issues are that you can’t use the Apple toolchain, so creating keys to sign apps with took me hours rather than minutes (it’s built into Xcode). Uploading an app through Xcode is built in, through Rubymotion you have to build it and then upload it through Application Loader. Managing image resources in Xcode is a breeze. Look at how simple it is to see the various app icon sizes that you need. Compare that to Rubymotion where you’ll be flipping between a file listing, a Rakefile and Apple’s Human Interface Guidelines.
Managing images, like everything else in Rubymotion, is done in code. So you'd better know your required image sizes and names. Which you won't, because you're just starting out.
Xcode knows what sizes of images you need for the devices and iOS versions that you are supporting.
Finally, using Rubymotion I could never get Testflight to work so that I could beta test the app. This might have been something that I was doing wrong but, at the risk of flogging a dead horse, using Rubymotion puts you outside the scope of 99% of the Stackoverflow questions and previously solved problems.
Web developers: Go straight to Swift.
I built and released this Swift app in four weeks of stop-start work. I’d never coded anything native before. Swift has such good error messages and syntax checking that you almost have to go out of your way to get it to fail to build. I think Rubyists will love Swift - it has its own beauty and a lot of stuff just makes sense.
I’d more or less completed the app by the time I came across the excellent course being taught at Stanford by Paul Hegarty, but I’ve been following it on iTunes University since I finished. I think that course, combined with the Appcode book, will have you able to create a complex, universal, database-backed app within four weeks. And enjoy the process.
I'm Alex Muir.