Mobile Zone is brought to you in partnership with:

I love technology. Plain and simple. You can generally find me writing software, figuring out how to get rid of cable, playing on my Xbox, or traveling around this country speaking about software development. If you're doing something cool with technology, let me know. I'd love to hear your story about something amazing. You can find my blog at jeffblankenburg.com Jeff is a DZone MVB and is not an employee of DZone and has posted 71 posts at DZone. You can read more from them at their website. View Full User Profile

31 Days of Windows 8 | Day #8: Local and Roaming Data

11.13.2012
| 3103 views |
  • submit to reddit

This article is Day #8 in a series called 31 Days of Windows 8.  Each of the articles in this series will be published for both HTML5/JS and XAML/C#. You can find additional resources, downloads, and source code on our website.

advertisementsample

In several of the articles in this series, we have mentioned that storing data is not only incredibly important, but also that it’s super easy to do, both locally to a device, as well as roaming across the many different devices a user may use.

Microsoft offers us some specific guidance on when to use roaming vs. local storage, but I’ll give you a quick summary here so that you’ve had a chance to read it (because we both know you didn’t click that link).  Again, these are guidelines, so you’re not going to get denied from the store for breaking these rules, but there are also limits to data transfer size and speed.  Exceeding those will prevent your app from actually roaming data for a period of time.

DO

  • Use roaming for preferences and customization.  Any choice that a user is likely to make on each machine that they use should be roamed.  These are basic settings, like color preferences, favorite actors, or whether or not to publish data to Twitter.
  • Use roaming to let users continue a task.  Having my browser favorites follow me around, or even my high scores is awesome.  Allowing me to continue writing that email (or blog post) I never finished? Even better.

DON’T

  • Use roaming for information that is clearly local-only.  This includes things like file paths and other data that only makes sense to the local device.
  • Don’t roam large datasets.  There is a quota, which you can determine in code, that limits the size of your roaming dataset.  It is best to only roam preferences and small data files, as we will show in this article.
  • Don’t use roaming for instant synchronization or rapidly changing data.  Windows controls when and how often your app data will be roamed, so don’t count on instant synchronization.  Build a web service of your own if you need this kind of reliability.  Also, don’t update the roaming data constantly.  For example, you don’t need to roam the user’s current location at all times, instead update it every minute or so.  You’ll still provide a rich experience without destroying your quota.

One last thing to remember: the way data is roamed across devices is managed by the user’s Microsoft account.  If they log into two machines with the same account credentials, AND they install the same app in both places, THEN the roaming settings and files will travel.  Until then, nothing happens.

Now that I’ve scared you into never using this, let’s take a look at how it’s done.  There are two types of data that can be stored, and we will address each one of them both locally and roamed.  First up is Settings, followed by Files.

Local and Roaming Settings

When you hear the word “settings” in Windows 8 (or even Windows Phone) development, “small, simple data” is what should come to mind.  We’re really talking about storing name/value pairs.

Good examples of these are user preferences.  Perhaps you stored the user’s first name (a string value) so that you could address them as such in your game.  Maybe they decided to turn off notifications (a boolean value) from your app.  Settings are also one of the easiest ways to store data, and I’ve found myself on more than one occasion storing a great number of settings values in my applications. Because these are invisible values that live in an invisible data store, I’ve chained a set of methods together that will create, then read, and then delete the settings values, both locally and roaming.  You’ll see that it’s actually pretty simple to use.

ApplicationDataContainer settingsLocal;
ApplicationDataContainer settingsRoaming;
 
string currentBook;
int currentPage;
        
public MainPage()
{
    this.InitializeComponent();
 
    settingsLocal = ApplicationData.Current.LocalSettings;
    settingsRoaming = ApplicationData.Current.RoamingSettings;
 
    AddSettings();
}
 
private void AddSettings()
{
    //There is no reason to set the same data to both local and roaming.
    //This is here merely for illustration of HOW to do it.
    //You should make the choice as to whether your data should be roamed.
 
    settingsLocal.Values["currentBook"] = "Hitchhiker's Guide To The Galaxy";
    settingsLocal.Values["currentPage"] = 42;
 
    settingsRoaming.Values["currentBook"] = "Hitchhiker's Guide To The Galaxy";
    settingsRoaming.Values["currentPage"] = 42;
 
    ReadSettings();
}
 
private void ReadSettings()
{
    //If you want typed data when you read it out of settings,
    //you're going to need to know what it is, and cast it.
 
    currentBook = (string)settingsLocal.Values["currentBook"];
    currentPage = (int)settingsRoaming.Values["currentPage"];
            
    DeleteSettings();
}
 
private void DeleteSettings()
{
    settingsLocal.Values.Remove("currentBook");
    settingsLocal.Values.Remove("currentPage");
 
    settingsRoaming.Values.Remove("currentBook");
    settingsRoaming.Values.Remove("currentPage");
}

In the sample project, you can set breakpoints at the beginning of each method, and then use Visual Studio to inspect our settings values in the Locals tab.

Here is what my data looks like after AddSettings() has executed (click to enlarge):

8-XAML-SettingsAdded

Now, after I’ve read the data from settings and stored it to values in my page:

8-XAML-SettingsRead

Finally, after my DeleteSettings() method has executed:

8-XAML-SettingsDeleted

As you’re building your apps, it’s important to remember that all of this data, both settings and files, are sandboxed to your application.  What this means is that when your application is uninstalled, all of the values are gone with it.  This also means that when you’re building an app that uses these values, and you want to start with a greenfield user experience, you might want to uninstall the app from your machine before testing it to get rid of any legacy values that may have been saved earlier.

In addition to saving these name/value pairs, you might also want to categorize them a bit.  We can create categories of settings, which makes adding and removing groups of settings very simple to do. This can also obviously be done both locally and roaming.  Here’s a look at creating a category, and adding a setting to it:

settingsLocal.CreateContainer("mediaSettings", ApplicationDataCreateDisposition.Always);
settingsLocal.Containers["mediaSettings"].Values["Volume"] = 11;

So we’ve taken a deep look at Settings, let’s move on to files now.

Local and Roaming Files

Files operate in a very similar way to settings, except that we are actually reading and writing the values to the hard drive, and I’ll demonstrate that in this example as well.  I’ve set up an identical set of methods to the ones we used in the Settings section: an AddFile(), a ReadFile, and a DeleteFile() method.  Here’s a look at the code:

StorageFolder folderLocal;
StorageFolder folderRoaming;
string fileName = "tacotext.txt";
string fileContents = "taco";
        
        
public MainPage()
{
    this.InitializeComponent();
 
    folderLocal = ApplicationData.Current.LocalFolder;
    folderRoaming = ApplicationData.Current.RoamingFolder;
 
    AddFile();
}
 
private async void AddFile()
{
    StorageFile fileLocal = await folderLocal.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
    await FileIO.WriteTextAsync(fileLocal, fileContents + "taco");
 
    ReadFile();
}
 
private async void ReadFile()
{
    StorageFile fileLocal = await folderLocal.GetFileAsync(fileName);
    string textLocal = await FileIO.ReadTextAsync(fileLocal);
 
    fileContents = textLocal;
 
    DeleteFile();
}
 
private async void DeleteFile()
{
    StorageFile fileLocal = await folderLocal.GetFileAsync(fileName);
    await fileLocal.DeleteAsync();
}

As you can see, the only major difference is that we async/await in our methods that rely on reading the hard drive.  We don’t have to specify folder locations, we don’t even have to define a folder structure if we don’t want to.

In addition, you can look at your files as they are saved.  Each application stores its files locally on the machine, and if you use a breakpoint, you can determine that location on your device.  For instance, the tacotext.txt file that I’ve created is stored at the Path property shown below:

8-XAML-FileStoragePath

Once you’ve created it, you can actually crack the folder open and see the contents, even open the files yourself:

8-XAML-FileLocation

Otherwise, that’s about it!  Saving files, even large files, can be done this way.  You only need to remember the file name that you gave them.  The Windows 8 sandbox takes care of the rest.  Please note that my example above actually only stores a local file, but that you use the EXACT same code (with a reference to ApplicationData.Current.RoamingFolder instead) for Roaming files.

As a reminder, roaming files will not transfer immediately, so don’t expect the type of performance you’ve seen with Skydrive or DropBox’s applications.  Be mindful of the data quota, but otherwise, use this stuff extensively. 

Settings and Files are a powerful tool in our Windows 8 development arsenal. It’s easy to do, and makes your application so much cooler when it lights up multiple machines at once.  I still tell stories about the first time I played Jetpack Joyride on a second machine, and all of my purchases, jetpacks, equipment, and settings showed up immediately.  It made what is an already awesome game that much better for me.  So much so that I’m recommending you pick it up yourself.  (It’s a free game, but there’s an in-app purchase option for $1.49 to double your coins from each level completed.  Totally worth it.)

8-XAML-JetpackJoyride

To download all of the sample code from this article, click the icon below:

downloadXAML

Tomorrow, we are going to discuss Live Tiles, and how we create both primary and secondary tiles, as well as how we update them.  See you then!

downloadTheTools

Published at DZone with permission of Jeff Blankenburg, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)