How I built my first iPhone app
Download the app by clicking here.
Yesterday, my first iPhone app Day Plus launched in Apple’s app store. Though the app is pretty simple by most people’s standards, the road to building it was really challenging. I wanted to write a blog post that talked about both my technical hurdles and the headspace/mindset challenges I faced, hoping this will help someone else.
Why specifically choose to build an iPhone app when I’m a web developer? There were two main reasons: Firstly, I really like the idea of building a product and making passive income from it.
Some people choose to build premium WordPress plugins or other web based products. Indeed, this would probably be the more practical route for me. A while back when I first started this blog, I wrote a post about a Pardot landing page template I built. That’s turned into one of the biggest sources of organic traffic to this blog, I could probably drill down into that and build something which would generate revenue. The problem is, that sounds extremely boring to me. Building iPhone apps just seemed like way more fun. I knew going in that the app store is challenging and I will have to fight pretty hard to carve out a piece of it for myself, but I plan on giving it my best shot.
Secondly, something I am trying to get better at is shipping. I often get ideas for projects, then imagine them becoming huge. Then I have all these ideas for features and if I don’t add such and such feature then the project will never take off. Eventually my enthusiasm fizzles and the thing never gets off the ground. Building a simple, small in scope app that I can iterate on appealed to me.
I decided I wanted to do this back in mid-March, and I got to work.
Doing it the hard way
Going in, I dismissed the idea of using React Native or something similar to build the apps. I probably could have gotten this app built much, much quicker using that tool or something equivalent, but I’ve heard that those products can be pretty limited and often don’t function as well as native apps. Plus, it kinda felt like cheating.
The second big technical decision I made somewhat early on was to build the UI completely programmatically. For people not in the know, Apple has a system called “Interface Builder” that allows you to drag and drop user interface elements and connect them with code. I was not a fan of this setup at all. It felt very janky to me and I am used to writing everything in code. This was definitely a much harder road to take, and I am not sure in the end if it was worth it.
I didn’t realize I had this expectation going into this project, but I actually thought it would all be pretty easy. After all, it’s one programming language, and you know exactly what devices you’re optimizing for right? It’s not like web development where it’s a chaotic ecosystem of libraries and frameworks that rise and fall in popularity and you have to test in a bunch of different browsers.
Also, I had read about Swift when it first came out. I assumed that Apple had smoothed out all the rough edges of developing apps and the learning curve would be pretty small unless I was trying to be real fancy. I was wrong!
Swift is a very strongly typed object oriented language. It’s a completely different paradigm to work in. It took me two weeks of studying Swift before I could even do basic algorithmic stuff and for loops without XCode barking at me. I am very glad that I spent several weeks just trying to learn Swift before actually doing app development, I think I would have been too frustrated to keep going if I hadn’t.
When in doubt, use a CocoaPod
There are several package managers for iOS development. I ended up using both CocoaPods and Carthage because one package I needed didn’t have CocoaPods support.
You’d expect to use third party packages when you need a special kind of UI functionality or animation, but the thing that really surprised me is how much I ended up relying on these packages for very core app functionality.
For laying out the elements on the screen, I used TinyConstraints which has a much simpler and more declarative syntax than the official Apple way of doing things. For storing data on the phone, I ended up using Realm because Apple’s way of doing things, called Core Data, was a huge pain in the ass.
It got to the point where to save time, I didn’t even try to learn the “Apple way” of doing something. I just looked to see what the most popular way of doing something was and did that instead. If I could do it over again, I’d probably use something like Yoga for layouts since I’m very comfortable with Flexbox.
I think Apple understands that they have a long way to go on improving their native APIs. While I was building this app, they introduced SwiftUI which should improve things somewhat for building UIs, but I think they have a long way to go in other areas too.
My next project is going to be a game, and I just don’t trust SpriteKit enough to use it after reading horror stories so I am probably going to have to use Unity.
I hope this doesn’t come across as too negative, I now know that I went about things in a bit of an odd way and if I had spent more time doing tutorials and stuck to using the interface builder/storyboards I probably would have had a better time.
While this was my first app, I did not want to go the route that I think a lot of people go and make some kind of “todo list” app which is basically just a re-skinned tutorial. I wanted my application to be something people could actually use.
I knew I definitely couldn’t compete on features, every additional feature I added was quite a bit more time for me. Plus there are hundreds of other “day counter” apps in the store. So I decided to focus on a very basic feature set and use my design skills to try to make a user interface that stands out.
Even though the user facing functionality is pretty basic for my first version, I made sure not to skimp on other areas that are important for user engagement and retention. I added a package that prompts the user to review the app after several uses, and Firebase so I could get an idea of how many people are using the app and how to improve retention etc…
Sticking to my requirements, but knowing when to cut a feature
I did something that surprisingly I have not done for many other projects I have built. I sat down and wrote a requirements list for version 1.0. Part of the reason I did this is because every time I described the app to someone they had a different suggestion for a potential feature and I found I was sitting down and kind of aimlessly exploring different options. Building a requirements list gave me a solid check list of items to get through and I knew exactly what was going in.
I did end up having to cut a few small things. For example, there is a progress indicator in the top left corner of the app that visually displays how much of the day has gone by. I was able to get this working but really wanted it to be animated. After spending 5 hours trying to get animation working and feeling lost, I decided to move that feature to a future release.
After I finished the app earlier this week, I was in a lot of fear that it would be rejected by Apple for being too simple. I lurk a lot of iOS developer forums and apparently there has been a large increase in rejections because of this. I thought that maybe I should try to add some of my features that I have planned for my next version.
But I looked at my initial requirements list and saw that I had completed all the items and decided to submit it anyways. I felt the app was complete for a version 1.0 and if Apple disagreed then I would proceed from there.
Where to go from here
I’m really happy that I now have a product I can market, and I’m going to learn about increasing app installs and every aspect of promoting it for a while before I work on a next version. This blog post is the first step in promoting the app, in a way.
This project was really challenging for me. I’m working on a very large project at my day job right now (a recode of a large data mapping system in React) and sometimes I would come home feeling drained, and still put the time in. I would guess some days I was coding for 12+ hours and feeling like I was making very little progress. But it made me a better programmer and a better shipper so I’m happy I went through it, even if Day Plus doesn’t end up being a success.