One thing that I think can be a little tricky when writing apps is how to manage how your app's data as it moves around between its various components.

For example, I was working on an app that tracks "tasks" (you know: feed the cat, remember to wear pants etc.) and I designed it to have multiple pages in order to view the tasks in different ways (overview, task editor, list view).

The question that immediately resulted was: what's the best way to allow each of these views to access the same list of tasks, make changes, and communicate with each other what they've done?

Obviously sketching something on squared paper is the first thing to do, so I did that:

 

That took five minutes, but it didn’t really help much. So I added this part:

 

That helped a little, but still it was only a drawing and my dream project to convert line drawings into source code hasn’t gotten very far as yet.

Initially I stored all the tasks in the same place that the app stores its settings. I'm not entirely sure why I thought this was a good idea, but it worked. Until I added more than 10 tasks, and then it threw exceptions like crazy. The app settings area is not designed for lots of data, so don't do this. Instead, use Windows.Storage.ApplicationData.Current.LocalFolder which is similar but designed to actually store data. Here's a topic on storing settings, and here's one on storing data.

The trouble with Async

Having File Handling APIs which work asynchronously is great, because your app can go get on with things, whilst the boring stuff happens in the background. This makes your app appear a lot more fluid and responsive, which is important in these days of tablets, touch and attention spans measured in units of Angry Birds. (One Millibird = 0.01 of a second. Your app should always respond within 10 Millibirds).

However, if you are being an ejit and saving and loading your entire task database between pages, then this will not work so well.  And I bring this up, because I discovered that in my app, when the user re-visited the overview page (which had a lot of XAML objects, several for each task), it worked best to re-create the page each time it appeared. And that meant reloading the tasks each time. And that was making things go weird. Very weird.

The solution was to not be an ejit, and to store the tasks internally, in a place that all the pages could access. So I created a List<> of the task objects, and stored that list in a singleton – a static class that always exists (rather than becomes instantiated), and which can be accessed by all other classes in the same Namespace.  So, where it says Data in that second diagram, it now means static class.

 

Surprising suspensions

This solved most problems, but there was a big one remaining. I obviously still needed to save the task database, so that it would persist between application launches.  I most definitely did need to do the File Handling to save it to disk, but only when the app was likely to disappear. So, I added a handler to the OnSuspending method (and remember you can do this in any class, not just App.Xaml.cs) and triggered the save from there. Unfortunately this had the nasty habit of deleting all the task data, rather than saving it. What was going on?

I found the answer to my prayers on this Stackoverflow posting. The issue is that OnSuspending doesn’t want your app to hang around. Once it’s got the “go away!” message, it needs to go away and fast. Once that OnSuspending method hits an await call, then that’s definitely all the time it’s going to get. Sadly, saving data takes TWO await calls: one to create the file, and one to write to it. My app was creating the file (thus erasing any previous content) but not saving anything to it. A perfect storm of bad data.

The solution was simple enough: ask for a deferment which wraps up the saving code into one definitely-let-me-finish bundle, and everything is safe.

private async void OnSuspending(object sender, SuspendingEventArgs e){                       
     var deferral = e.SuspendingOperation.GetDeferral();                       
     await Save();
     deferral.Complete();
}

Definitely something you either know or you don’t. I do now, and I hope you do too.

 

Updating Tiles

I also took the opportunity to add a little number to my app’s tile to display the current number of tasks. This was ridiculously easy. After iOS’s rather rigid view of what an app icon can be, it’s refreshing to be able to change the image, text, badges etc right from within your app. All it takes is a little code to look through some XML and change a value: like this:

 

void updateBadge(int numberOfTasks)

        {

            XmlDocument badgeXml = BadgeUpdateManager.GetTemplateContent(BadgeTemplateType.BadgeNumber);

            XmlElement badgeElement = (XmlElement)badgeXml.SelectSingleNode("/badge");

            badgeElement.SetAttribute("value", numberOfTasks.ToString());

            BadgeNotification badge = new BadgeNotification(badgeXml);

            BadgeUpdateManager.CreateBadgeUpdaterForApplication().Update(badge);

        }

 

This is just the simplest option. You can also register your app to run in the background, and change tile data depending on external input – your app could poll a web service and update its tile with new values, and your users will be quietly impressed.

Gratuitous Advert

The app is on the Windows App Store now, in case you want to see it.