Epic rant about the trials and tribulations of building a Mac app follows. I’ve decided to lay it out with warts and all so I can reflect on the process. Hopefully it provides some insight into how an app gets made and helps other developers avoid some of the mistakes I made along the way.
It started the way all my apps start. I had a problem I needed solved.
I had taken to using Twitter to respond to feedback about my apps. I’ve mostly stuck with using the Twitter website on my Mac and only use a dedicated client on my iPhone.
This was fine, the only problem was that when I had the Twitter website closed I would miss peoples mentions. What I wanted was a simple app that would let me know when I had new mentions waiting.
I headed to the Mac App Store and did a search for ‘twitter notification’ – here’s what comes up when you search for that:
Bird Bell was the only app that looked promising, the others definitely didn’t do what I needed. I installed BirdBell but found that it didn’t notify you when you get mentioned, only when someone follows you, retweets you or adds you to a list.
I hunted around for a while but I couldn’t find a simple app to notify me. I finally asked on Twitter:
A few ideas came back, I could setup a dedicated email account, get mention notifications sent there and then use a mail notifier app to show me notifications for this account, or I could setup SMS notifications to my phone. Ugh. The last thing I want is Twitter taking over my phone as well.
No problems, I thought – I’m a Mac developer. I can whip up an app to do this in no time. Maybe I can even put it on the Mac App Store and sell a few copies. Looking back, I can only laugh at how naive I was. What I thought would be easy and only take a few weeks to develop would end up being a five month long nightmare project that the universe would try very hard to stop me shipping.
I fired up VoodooPad and started drafting out my masterpiece. This is what I came up with:
As you can see, the idea was simple enough – I didn’t think the app would need a full user interface, just some basic preferences and a menu item. I also thought I would have the app simply poll the public Twitter search API, that way I wouldn’t need to worry about handling authentication. You simply give it the username you want to check and the app requests http://search.twitter.com/search.json?q=@johnwinter every now and again and checks if there’s anything new there.
I went ahead and coded up a prototype. Here’s a quick demo I recorded at the time:
As you can see, my initial design was pretty rough, but it got the job done.
Around this time it occurred to me that the app would need an icon. I sent the video and some ideas I had for the type of icon I wanted (below) to Taher – a designer friend of mine and asked him to have a go at it.
This is what he sent me back:
I was thrilled with that, and he also convinced me to change the name to Tweetifier. But now I felt that the app design wasn’t good enough for the icon.
After some more discussion, Taher did a completely fresh design for the app:
Although I was initially reluctant to increase the complexity of the app by having a full feed display, seeing this new design convinced me otherwise. I decided it would be nice to be able to see my mentions and also reply to them.
I went ahead and implemented the new design, starting with the updated status item. Here’s a short video I recorded:
Much nicer than my first prototype, but the main UI still needed implementing.
Apple change the game
Around this time, Apple held their yearly Worldwide Developers Conference (WWDC) in San Francisco and released the MacBook Pro with Retina display. I decided that if I was going to release Tweetifier on the Mac App Store, it should look great on these new MacBooks. This would mean doing two separate versions of all the app artwork, one version at the standard size and one at double size (2x) for the new displays.
The other thing Apple announced at WWDC was OS X Mountain Lion. I remember watching Craig Federici demo the new Twitter integration – one of the features announced was the ability to display a notification when you received a new mention on Twitter. I was a little concerned by this, as it seemed like there would be little need for my app if Apple built the main feature right into the operating system. It would suck if my app was Sherlocked before I even released it.
I downloaded the Gold Master of Mountain Lion so I could decide if there would still be a need for my app after Mountain Lion shipped.
Initially, it didn’t look good. Setting up a new Twitter account on Mountain Lion was straightforward and I could easily set notifications for mentions and direct messages. I tried tweeting myself from another account and waited for a notification to appear. Nothing happened. I fiddled with the notification settings, removed and re-added the account, tried a reboot and looked for messages in the Console. I even installed Mountain Lion on a different machine, but I still couldn’t get the Twitter notifications working.
I googled around for a solution, but Mountain Lion was still under NDA and I couldn’t find anything about the issue. I had to assume Apple would fix this eventually though and if their notifications would actually work it could still spell trouble for my app. In light of my findings, I decided to continue on with the app but planned to add some extra features not offered by Mountain Lion (more on that later).
The scope changes
I finally got the main UI working and got the app checking Twitter for mention updates. This brought to light a new problem – the Twitter search API for unauthenticated requests was very restrictive in terms of how many requests you could make. Unauthenticated calls to the Twitter API are limited to a maximum of 2 requests per minute. This meant two things:
- There would always be about a 30 second delay between a new tweet arriving and the user getting notified about it
- Multiple account support would make this delay much worse as the two requests per minute would have to be shared among how ever many accounts the user had added
I decided this was less than ideal and began researching the Twitter streaming API – with the streaming API you open a long running connection to Twitter and they push new tweets to you as soon as they arrive. It was perfect for a notification app, but it came with a major downside – I would have to implement Twitter OAuth authentication in the app.
I had planned to develop the app in a few weeks, but the scope of the app was now rapidly expanding. Instead of my orignal, simple app idea – I now wanted:
- Twitter Streaming API support
- A feed display
- Retina display support
- More features so the app could hold its own against Mountain Lion Twitter notifications
The Tweetifier codebase rapidly grew. Although there were a number of useful libraries I was able to use to help my app communicate with Twitter (OAuth Consumer & SBJson), I still ended up writing several thousand lines of code myself to get streaming working. I spent many weeks testing and fine tuning to get the app working reliably with the Twitter API.
I ran into many strange issues, sometimes a tweet would not be delivered at all via streaming in which case my app would have to fallback to the REST API and fill in any tweets missed. Other times, the tweet would show up via streaming but then wouldn’t show up in the REST API. It took a long time to work through these issues. There are also very strict policies that a Twitter client must follow that cover things like, how often to retry upon being disconnected, how to handle rate limits, response codes, API keys and many other things.
I had no idea that making my app talk with Twitter would require so much work, and things were about to get worse.
Twitter change the rules
In August, Twitter announced new rules for using their API. The new rules discouraged the building of Twitter clients by limiting the number of users an app could have and also added new display requirements for apps. While I felt that Tweetifier could fit within these requirements for now, it made me anxious to be developing an app for an API that might go away soon.
The new Twitter API rules combined with the Twitter notifications built into Mountain Lion were starting to make my great idea start to look like not such a great idea after all. Again I had to make a decision as to whether I should continue with the app. I wasn’t feeling great about the project at this point and it’s hard to make yourself work on something that doesn’t seem to be working out. One of my friends politely suggested I abandon the project. Things looked grim.
Glimmers of hope
By late August I had the app more or less working – it just needed Retina display support, the ability to reply to tweets and a lot of bugs to be fixed. I was already finding it highly useful for myself. I tried to focus on the upsides – The Tweetifier codebase was clean and tidy, the visual design of the app was extremely good and I’d learnt a ton about OAuth and Cocoa while building it. I’d also been testing out App.net, a Twitter alternative with a far more developer friendly ecosystem that launched around the same time Twitter announced their new rules. If things really turned sour with Twitter I figured I could perhaps turn Tweetifier into an App.net client later down the track. Adapting Tweetifier to work with App.net should be fairly straightforward.
I also felt that I couldn’t possibly throw out all the gorgeous design work that Taher had done (example below). I pushed on with the app.
By late October I had all the main features of the app working. Twitter streaming was working well, you could easily reply to mentions and I had integrated over 80 images required for the Retina and non-Retina UI into the app.
In the meantime, I’d had a an idea for another feature that I thought tied quite well into the app. Since the app was sort of a selfish Twitter client (in that it only showed mentions and notifications that are about you) without showing you the main feed, I thought it would be nice if it could also tell you how many followers you were losing/gaining. I called this new feature Widgets. It gives you movable Widgets that sit on your desktop and show info about each of your Twitter accounts.
The numbers in brackets give the change in followers/following over the past 24 hours. So I can see my @johnwinter account lost 6 followers while my @aptonic account gained 17 in the last 24 hours. I spent a few weeks developing Widgets, writing a preference pane to control them and then ironing out the bugs.
After releasing a beta to a few hundred users on Twitter to fix any major bugs I missed, the app was finally ready for submission to the Mac App Store. I sent it to Apple for review on the 23rd of November and waited anxiously. If they rejected it, it likely wouldn’t make it into the store until long after the iTunes Christmas closedown from December 21 to December 28 during which Apple don’t review apps. While I waited impatiently, I worked on the Tweetifier website and got it ready for the launch.
Finally, 14 days later on December 6th Apple approved the app! I was thrilled. It had been a long and trying journey but I had learnt plenty and managed to make an app that I was proud of.
It therefore gives me great pleasure to announce that Tweetifier is available today on the Mac App Store. Take a look at the app website I did and check out the video and screenshots on the app store. Or better still, go and buy the app from the link below – it’s only $2
I’d like to mention that getting the app in the store is really only the beginning, as I alluded to in this post there are many more features I’d like to add such as App.net support, the ability to run a script when a tweet arrives, a keyboard shortcut to open Twitter and a few other ideas I have. I’m hoping to release some great updates to the app in the coming months.
Finally, I’d like to say a huge thank you to Taher who did an outstanding job with the design of the app and gave me much help and encouragement along the way. I feel like this app is the first of my apps that has really been really well designed from the ground up and that’s largely thanks to the work of Taher.
If you have thoughts or questions on the app or on this blog post I’d love to hear, leave me a comment either here or on Hacker News.
Thanks for reading!