Padee v2.1.0

I finally released a new version of Padee on the App Store, and I wanted to write a post about why it took so long & what's in the update.

What took so long?

I take a shamefully long amount of time to put out updates for apps in general. That's mostly because a.) I work on my apps outside of a full time job, life, etc., and b.) I'm never satisfied with my own work. This update also had the added bonus of containing a big & potentially dangerous change: how user drawings are stored and managed in the app sandbox.

That's a big change, and if I made a mistake then there's a very real possibility that people will lose their drawings. I was not willing to risk that for the sake of pushing an update out. Below are some technical details about what went into that change.

The details

First, a rundown of how user sketches were saved. Initially, drawings were saved on disk as archives. The Sketch class conforms to the NSCoding protocol, so saving sketches was simple:

NSKeyedArchiver.archiveRootObject(sketch, toFile: sketchURL.path)

And restoring sketches was just as easy:

let archiveData = try? Data(contentsOf: sketchURL.path)
let archive = NSKeyedUnarchiver.unarchiveObject(with: archiveData) as? Sketch

Starting in version 2.1.0, Sketch instances are saved as properties of a UIDocument subclass. Before this I had only a passing familiarity with UIDocument, so the architecture I’ve ended up with is the result of some trial and error, lots of reading through documentation, and some StackOverflow searches.

I initially changed all of my view controllers to use the document subclass, but it caused my code to quickly become unnecessarily complicated. The various asynchronous document methods made it more difficult to reason about the order in which things were going to happen. I also experienced a slight drop in the responsiveness of the app.

I wanted to remove the responsibility of handling documents from my view controllers, so I moved all of that functionality to a separate file manager controller. The public methods of this controller that handle sketches take an optional completion handler, similar to the UIDocument methods.

What I ended up with was a flow that I felt much better about:

  1. My main view controller could handle creating sketches as before.
  2. When a sketch is saved, the view controller simply hands the Sketch instance to the file manager controller. Here is where the view controller’s responsibility for the Sketch ends.
  3. The file manager controller takes the Sketch, creates a new document (if needed), and saves said document.

Because the document creation/saving wasn't blocking a new Sketch instance from being created, I was able to maintain the same responsiveness as before.

In hindsight it’s all so obvious, but there was a lot of code churn leading to this conclusion. Not to mention I tested & re-tested and then re-tested my re-testing. I just really did not want to lose any user data because I was too lazy to test an edge case. Thankfully, the update has been completely rolled out (iTunes Connect’s staggered rollout feature is awesome) and I haven’t received any crash reports or support requests about loss of data (yet). So for now I’m going to breath a sigh of relief.

For better or worse, Padee’s code is up on GitHub. Feel free to check it out.

Daniel Strokis