Airmail Journal #1

The story [begins | continues] - delete as appropriate

Inspired by Brent Simmons' series of blog posts about implementing syncing in Vesper, I have decided to chronicle my own work in building a sync engine for Envelopes. I intend to use these posts as a way to keep track of all my ideas as I have them. And also as a way to hold myself accountable for the development - I often have motivation issues when it comes to writing my own software.


I have already decided that the sync engine will be called Airmail (get it?), hence the post title. This will be my second attempt at writing it; I have previously completed around 50% only for circumstances to make finishing it impossible. The work I already have is mostly useless in light of what I have learned (and Apple has changed) since then.

Since I released Envelopes in 2010, syncing is by far my most requested feature.


Before starting again, it feels appropriate to list what exactly I hope to accomplish with the sync engine.

It will be a premium feature.

The cost will be subscription based rather than a single payment. This introduces the concept of account expiry and all the headaches that go with it (informing the user, restricting access, eventual removal etc.).

Payments will be taken initially via in-app purchase, but in the future it should be possible to take payments in other ways. It should also be possible to grant promotional free periods to customers at my discretion.

The concept of an account should be exclusive to the server.

Usernames and passwords are tedious, I don't like them. I also don't like the idea of storing a password on my servers that is potentially used for an online banking account or the like (not everybody uses 1Password) - it seems like every other week another story comes out about leaked account details and password hashes. I don't even want to go near something like this.

The goal is sharing data.

Customers of Envelopes typically want their spouse or significant other to be able to modify the same dataset, rather than struggling with the logistics of having a day phone and a night phone.

So, a user needs to be able to invite someone else to share the data in their account. This mechanism allows me to avoid usernames and passwords, but still solve the day/night phone problem if needed. The one issue with this approach I've thought of (so far!) is account recovery: say a user accidentally deletes Envelopes from all the devices connected to their account, they now can't invite themselves to join again.

It needs to be secure.

Envelopes is a financial management tool; the data is inherently sensitive. Ok, so I'm not exactly storing credit card details, but most people wouldn't like the idea of an attacker seeing how much they spent on sex toys last month.



In my first attempt at the web service I used Rails, but I'm now planning to use Node.js much like Brent. I like the single process model, and I like closures. I'll be using it with a relational database system, rather than a trendy NoSQL alternative.

On the device I use Core Data for persistence and I have no intention to change this. Despite the fact that a lot of people dislike Core Data (for perfectly valid reasons), over the years I've become quite adept at making it perform even with huge datasets - and Envelopes isn't exactly the kind of app that creates huge datasets in any case.


I use Xcode for Cocoa development, and Sublime Text 2 for everything else. If you're wondering why I use Sublime Text 2: I made this decision some time ago for several reasons (mainly personal taste).

Sublime Text 2 is also not the kind of editor I would usually entertain, but it works, I know the keyboard shortcuts, and it's very powerful once you learn how to use it.