(This is part of an ongoing series of posts about my experiences in building, releasing, and promoting my first iOS app Remembary: The Connected Diary for Your iPad. Several posts are expanded from a presentation I gave in January. There's an overview here.)
One of the common worries I had heard a lot was: "What if the app gets really popular, but then it turns out there's a terrible error in it? We'll look bad in front of the whole world!" This worry manages to combine two delusions at the same time: wish fulfillment and paranoia. It's a close cousin to the endless worries that web-app founders have about how things will "scale".
I started getting this worry myself every time a Remembary release got closer to going live. I countered it by 1) having a thorough QA checklist that I run through at least twice (once in the simulator and once on the device) before submitting to the store, and 2) reminding myself that this is just a neurotic worry that's doing more harm than good.
Unfortunately, this audience wasn't completely happy. I started getting emails from the website's support form, the review article started getting angry comments, and, worst of all, Remembary started getting 1-star reviews in the App Store. People were saying that Remembary was doing the absolute worst thing that a diary app can do: it was deleting their entries!
What made this even more like a bad dream was that I had been using Remembary myself almost daily since the time that it was just a text field and some buttons on a grey screen, and I had never experienced this problem. I checked with some of the other users who had contacted me before, and they reported that everything was working fine - so the problem was only happening to some people, but not everyone, and - most maddening of all - not me.
If Remembary had been on another kind of platform, like a Windows PC or Android, I could have explained this away as some kind of strange hardware incompatibility - but at this time there was only one kind of iPad. Everyone was using basically the same device as I was, but some of them were having trouble.
So, in light of this, there were two things that I had to do:
The PR part is worth an entire post on its own, which is coming up next - but here's how I found and fixed the problem:
This led me to believe that the problem wasn't in the data layer, but through some kind of interface activity. One of the things that make iOS apps feel so natural and intuitive is that they don't have "Save" buttons - content should just be persisted automatically without the user thinking about it. This silent saving is one of those seemingly simple things that actually take a lot of work: I had to figure out all of the cases where someone might change their context, and make sure that the current entry was properly saved in all of them. My guess was that there must have been some rare permutation of user actions that wasn't causing the save command to be called properly. So I advised people to try going to another date and then back before leaving the app - thus properly triggering the call to save the data.
Some people reported that this solved the problem for them, but other people were still losing data. I was completely flummoxed. I was using Remembary myself every day, and was trying everything I could think of to make it delete things, but I just couldn't reproduce the problem.
Remembary was now showing a score of 1 1/2 stars in the US store and had comments that said things like "I bought this based on AppAdvice's recommendation. Not so sure I trust them anymore" and "Reinstalled but not very confident... Hard to trust this at the moment." Sales had collapsed again back down almost to the level they had been at before the review. And I still couldn't reproduce or figure out the problem.
Then, one night I had been doing a lot of work on my iPad and had Pages, Keynote, Numbers, Twitter, and World of Goo open in the background and Remembary in the foreground. I switched over to The Early Edition RSS reader to check a reference from some article I had read yesterday, and it started automatically downloading from the 60 feed sources I have - I closed out of Early Edition and back to Remembary and discovered an empty page.
I had never, ever, been so happy to lose data in my entire life.
Now I knew what was causing the problem - and why I had missed it. The current version of Remembary had come out right around the time that iOS 4.2 had arrived, with its support for multitasking. I had of course updated Remembary to support going to sleep and waking up in this multitasking environment, and it had worked fine in all of my testing and in my day-to-day usage. Remembary isn't a particularly memory-intensive application - it's almost entirely text, and text is cheap. For example, I had done some testing with all ten years worth of Samuel Pepys' diary, and it had taken up only slightly more than 2 megabytes. I had triggered low memory situations in the simulator and the application had behaved perfectly fine. But I had never considered triggering a low memory situation while Remembary was asleep, and this particular combination was causing the problem.
This explained why I didn't experience the problem, but many of the new users did: I don't usually use that many iPad apps over the course of a normal day, so I rarely trigger low memory situations. The kinds of people who buy apps right after reading a review in AppAdvice are more likely to be running lots of apps, and thus more likely to run low on memory - and so more likely to see this problem.
It took them all of five minutes to find the problem and fix it.
Here's what it was: It turns out that when iOS apps run low on memory, they unload any views that aren't in the foreground. Then, when these views come back to the foreground, they're reloaded from the template files, but they aren't necessarily populated fully. One of the things I had added in the latest version of Remembary was a nice startup animation that presented a leather-bound book cover opening to reveal the diary (actually a 'default.png' and a modal view and some clever slight-of-hand). To ensure consistency and security (if the journal was password-protected), this modal view was brought up automatically whenever the app was put to sleep, so that it would already be showing when Remembary was woken up again. This meant that if a low memory situation occurred, the main diary page was now in the background and so was unloaded to preserve memory. That made it come up blank when the application was restored - and then the blank values got auto-saved to the database, deleting whatever diary entry was already there.
All that was needed to fix the problem was an extra few lines of view configuration in the viewDidAppear method and everything now worked. I spent a day running the app through the regular QA checklist (this time with extra checks for low memory situations while backgrounded) and, less than a week after first hearing about the problem, I submitted Remembary 1.3, complete with fixes, to the store.