What I Learned Building My First iOS App

Farecast for Uber

With the advent of Swift and the Apple Watch around the corner, I felt that the time was right to start learning iOS development in earnest. I’ve been down this road before. The ugliness of Objective-C and the seemingly endless red tape required to get into the App store thwarted my earlier attempts at app development. But this time was different, thanks to Quick Left’s internal iOS learning club and this series of video tutorials by Bitfountain.

After about a month of development, I was able to get my first app into the App Store, and have just recently hit 500 downloads! Here are some key takeaways I learned during my first foray into iOS.

Note: My app, the one described in this post, is Farecast for Uber. You can download it in the App Store.

Say goodbye to continuous deployment

On the web, it’s common to ship production code multiple times a day. If you discover a critical bug in your web app, you fix it quickly and push the code live. Done and done.

Unfortunately, that’s not possible on the App Store. Apple manually reviews every app store submission, including app updates, and this process can take up to several weeks. reports a rolling average of review times. As of this writing the average review time is 5 days.

What this means is that any changes you want to make without an App Store deploy must be done on your API. In my case, the first iteration of my app hard-coded the list of cities I was supporting. I came to realize that whenever I wanted to add a city (or a neighborhood in a city), I would have to submit an update through the App Store. That did not match with the aggressive pace I had planned in launching new cities, so I changed my app to query the list of cities from my API. This added some complexity, since I now had to handle a variety of edge cases for when cities were collecting their initial data, but it allowed me to ship “new” versions of my app without an App Store deploy.

This strategy can be extended to disable or enable features, change the theme of your app, and more, without every deploying an update through the App Store.

CocoaPods is amazing

CocoaPods is a dependency manager for Mac and iOS projects. They actually describe themselves as a “dependency manager for Objective-C projects,” but I found it works great with Swift too.

To pull in an external library, you add the library’s name to your Podfile, then run pod install. Rubygems users will feel right at home here. Like with a Gemfile, you can point a pod to a specific Github repo or branch. Cocoapods works on Swift projects by means of a bridging header. Not every Objective-C library supports Swift through bridging headers, but in my experience the most popular libraries do. Those that don’t often provide other means of Swift compatibility.

Think of marketing from day 1

Since I was just trying to get my feet wet with iOS development, I didn’t focus too much on marketing my app. Turns out that was a bad idea. The App Store is a crowded, crowded place, and without lots of positive reviews and press your app will go unnoticed.

If I could go back, I would have built marketing nudges into my app directly from day 1. An example of this would be those popups that prompt a user to review the app in the App Store. Reviews are crucial because Apple uses them to weight your app in search results as well as to determine if it belongs on any “featured on the App Store” lists.

It also wouldn’t hurt to build in Facebook, Twitter, and other social sharing links. I didn’t do any of this and my download numbers show it.

Swift is a pleasure

The announcement of Swift was the main factor that pulled me back into iOS development. I find its syntax clean and intuitive, and with the notable exception of optionals, the grammar is similar to JavaScript’s. And even though Swift is statically typed, the implicit type casting is very good, and Xcode is full of helpful popups when you make a mistake. For example, if you forget to prefix a variable with self. in a closure, Xcode will highlight the erroring word and say, “Did you mean to say self.myVariable?” The idE is full of smart hints like this that really speed up development.

Auto Layout is a bear; use Xcode’s helpers

We web developers are very comfortable supporting zillions of device sizes, and now iOS developers must be as well. Auto Layout is the mechanism in Xcode that defines objects’ sizes and their spatial relationship to other objects. Basically, you configure how much space should be between two objects, and iOS calculates what that actually means in terms of pixels on different iPhone screen sizes.

In practice, this is difficult to get the hang of. If just one of your many constraints is wrong, whole interface objects just won’t render. Xcode tries to warn you when this is the case; an orange guiding line means a constraint is wrong or missing. When this happens, select the erroring object, then at the bottom of your storyboard, click on “reset to suggested constraints”. (That button is inside a flyout menu). I found that this fixed my issues 90% of the time. Use this button generously to save time!

In conclusion

iOS is an exciting new platform for me, and I hope that others can learn from my n00b mistakes. Let me know your favorite Swift/Xcode tips in the comments!