January 27, 2013
In April 2012, coming off another technically interesting but commercially flopped side-project, I was in the process of convincing myself that I should really be sticking to my knitting when I came up with a cool idea for, yes, another side-project.
The concept was simple and resonated with my own needs, and I figured I could whip up a prototype fairly quickly to see whether it would be useful to myself and others.
So, with a working prototype in hand I (once again) imposed upon the awesome talents of Colleen Nicholson to come up with an app icon, and set about bringing this thing to market.
I'll do it over the weekend.
— Bill Gates
How long would it take? A couple of weeks to Beta, maybe a couple of weeks of that, and then submission to the Mac and iOS app stores. Launch in June, margaritas on the beach by Canada Day1.
The core UI was dead-simple. The magic was in the iCloud-based synchronization on which the whole thing hung. A little research and a little testing and I decided on the iCloud Key-Value Store API. Although primarily intended for storing user preferences and configuration settings, the API was sufficient for my needs and it was2 the simplest and most reliable iCloud sync option.
I needed to build a fair bit of intelligence on top of that layer. The original schedule was washed away by reality but as the weeks and months rolled past I eventually got the sync behaviour I wanted. This was no fault of iCloud: the Key-Value Store API was rock-solid and acceptably performant for me throughout my testing, but I had a lot of kinks to work out in my own code. It was November before I finally submitted the iOS and Mac apps for review.
Rejecting your own binary is not a nice feeling.— Gene Goykhman (@genegoykhman) November 23, 2012
Prior to the completion of the review process, a Beta tester discovered a show-stopper and, after messing around with the code for a bit, I decided to pull the binaries until I could get it right. Sync is hard, and if you screw it up people are going to lose data.
I spent the next few weeks hacking away on an experimental branch of my sync code, digging deeper and deeper until I could no longer see daylight. Throwing my hands up just before the Christmas holidays, I decided to shelve it until 2013.
Refreshed and re-energized in the new year, I took a step back and started writing lots of automated tests against my sync logic. One of my frustrations had been my inability to quickly identify regressions and test edge-case conditions quickly enough. So, as you do, I implemented a detailed simulation of the actual iCloud Key-Value Store against which I could test my sync logic.
Like a shaft of light from the heavens cutting through the gray skies, in early January everything came together in a smooth, reliable, fast, and tight little bundle. I released another Beta and almost immediately submitted the app for review.
The iOS app was approved in about a week or so, but a few days after that the Mac app was rejected. I was using the iCloud Key-Value Store to save actual user-generated content, and that's not really what it's meant for.
I'm not going to whine about the relative merits of this argument or the fairness of this rejection. The fact is that yes, I was using the KVS to store user data and that no, that's not what it's meant for. So now I'm back to the drawing board on (by far) the most challenging element of this app.
After 3 (or was it 4?) complete re-writes of the synchronization engine, the last including a fairly high-fidelity simulation of a chunk of iCloud, I think it's fair to say that my little weekend project has become a scope-creep cautionary tale. Part of me thinks it's time to shelve it for good. Especially since one of the most viable options now is converting the code to use iCloud Core-Data Sync (aka the Painmaker).
But I'm not very good at letting go of something once I've got it clenched in my jaws. So don't be surprised if a post not too long from now announces the release of this little project, a year or so after that first weekend prototype.
1. July 1st.
2. And still is, from what I hear.