The Imaginative Universal

Studies in Virtual Phenomenology -- by @jamesashley, Kinect MVP and author

WP7 Tip: tombstoning simplified

In order to prepare your phone app to go into tombstone mode (to make it tomb-worthy) it is necessary to save off state data associated with your app.  My preference is to simply save off view models – but you may want to also save off model objects or even individual field values.

There are two dictionaries for doing this. 

IsolatedStorageSettings.ApplicationSettings is available to save persistent data between runs of the application (whether the application gets tombstoned or simply gets closed down).

PhoneApplicationService.Current.State allows one to save and restore data when the application gets tombstoned.  It is handy if we only want to save off data temporarily – for instance if we do not need it for a fresh run of the application. 

Since State and ApplicationSettings are both dictionaries that automatically handle serialization and deserialization for us, much of the underlying code we are required to write when using them is also very similar.

In my own applications, I use a set of utility classes to ease saving and restoring my application state.

Since I generally only want to use State and ApplicationSettings to save and restore data, I encapsulate the plumbing behind a very simple interface.

    public interface IDataStorage
    {
        bool Backup(string token, object value);
        T Restore<T>(string token);
    }

The concrete classes aren’t particularly sophisticated.  I use this for transient data storage:

    public class TransientDataStorage: IDataStorage
    {

        public bool Backup(string token, object value)
        {
            if (null == value)
                return false;

            var store = PhoneApplicationService.Current.State;
            if (store.ContainsKey(token))
                store[token] = value;
            else
                store.Add(token, value);

            return true;
        }

        public T Restore<T>(string token)
        {
            var store = PhoneApplicationService.Current.State;
            if (!store.ContainsKey(token))
                return default(T);

            return (T) store[token];
        }
    }

And this for isolated storage:

    public class PersistentDataStorage: IDataStorage
    {

        public bool Backup(string token, object value)
        {
            if(null == value)
                return false;

            var store = IsolatedStorageSettings.ApplicationSettings;
            if (store.Contains(token))
                store[token] = value;
            else
                store.Add(token,value);

            store.Save();
            return true;
        }

        public T Restore<T>(string token)
        {
            var store = IsolatedStorageSettings.ApplicationSettings;
            if (!store.Contains(token))
                return default(T);

            return (T) store[token];
        }
    }

You’ll notice that the only real difference between these two code segments is that I need to call Save for isolated storage but do not have to for State updates.

Now when I need to save to isolated storage I simply call:

    var store = new PersistentDataStorage();  
    store.Backup("token", myObject);

While a transient save to State is simply:

    var store = new TransientDataStorage();  
    store.Backup("token", myObject);

No sticky kids mess afterwards.

I like having an interface as it allows me to throw some methods on the VMs themselves:

public static bool Backup(IDataStorage store)
{
    return store.Backup("MainViewModel", this._instance);
}

public static void Restore(IDataStorage store)
{
    this._instance = store.Restore<MainViewModel>("MainViewModel");
}

In this case, each VM is responsible for what actually gets saved to storage: for instance, we might want to save off the VM as well as the  associated model object. 

Whether this state is saved off to IsolatedStorage or State, however, gets determined elsewhere – generally in the ApplicationService lifecycle events: Launching, Closing, Activated and Deactivated.

Comments (11) -

Very nice.  Making the Restore method generic is a particularly nice touch.

Carpet Cleaning - Removal of Pet Dander and Odor in Carpets.....A pet for several people is equal to having an extended member of the family unit.....It can be joyful learning your pet's character and watching them grow.....Regrettably, the price of a pet goes further than the price you paid in the pet store.....

This fight of Khan vs Maidana will be on December 11. Let us watch it live.

Looks like an interesting story, just wish I was techie enough to understand it.

thats saved me a bunch of time with that code ,

the hardest part of tombstoning is to get that application to work properly but with this code it just made it a lot easier , but I still dont always do it right ugghhhh

You are a very smart person!

Carpet Cleaning - Removal of Pet Dander and Odor in Carpets.....A pet for several people is equal to having an extended member of the family unit.....It can be joyful learning your pet's character and watching them grow.....Regrettably,

nice post on programming

Recommend you to take a look at it, is now being discounted, Monster Energy Hats Collection in hot! Fashionable dc shoes hats Keeps with you at any time.

Good!Dear friends, thank you for visiting our website ,we are an international trade company . We at competitive price,providing a huge range of Jewellery。 You can buy cheap Pandora Jewellery. Welcome to visist here.

Pingbacks and trackbacks (9)+

Comments are closed