This blog post is part of a series about how Windows Phone 8.1 affects developers. This blog post talks about how to store application  data and is written by Robert Hedgate at Jayway and was originally posted here.

Introduction

In this blog post I will do a quick overview of what is new with application data in Windows Phone 8.1. This is the first impression of the functions so I do recommend you to take a look at MSDN if you want a deeper understanding of how it works.

 

What is the same as before

Saving data to local storage works as before. Here is a code example of how it could look like:
var localFolder = ApplicationData.Current.LocalFolder;
var localFile = await localFolder.CreateFileAsync("localFile.txt", CreationCollisionOption.ReplaceExisting);            
var fileBytes = System.Text.Encoding.UTF8.GetBytes("some text string");
using (var s = await localFile.OpenStreamForWriteAsync())
{
    s.Write(fileBytes, 0, fileBytes.Length);
}

What is new

Even before you could instead of targeting LocalFolder target RoamingFolder or TemporaryFolder. This code did compile however it did throw a not implemented exception when you ran the code. In Windows Phone 8.1 it is now implemented. The code structure is the same as before, just change what folder you’re targeting. This is exactly as it works on Windows 8.1. Another new function which is very useful is the FileIO.WriteTextAsync. This makes it very easy to write text to files:
var tempFolder = ApplicationData.Current.TemporaryFolder;
var tempFile = await roamingFolder.CreateFileAsync("tempFile.txt", CreationCollisionOption.ReplaceExisting);
await FileIO.WriteTextAsync(tempFile, "some text string");

TemporaryFolder

Why use the TemporaryFolder? This is the place where you can save data without thinking of have to remove it later. The data is saved between sessions but is removed when Windows Phone deem it necessary, e g running low on memory. Saving data between sessions is perhaps not the best idea but TemporaryFolder can be used for example for sharing data between several view when you for some reason don´t want to keep the data in memory. You can save images to the temporary folder for use in your views if you don´t want to persist them in your local folder. From XAML you can target the TemporaryFolder by using ms-appdata:///temp/. Example of image XAML:

RoamingFolder

This is a very useful function. If you save data to the RoamingFolder the data is available on every device the app is installed, of course only if you log in with the same id. Perhaps it is more useful on Windows Store apps because often you have more than one device. But now when the stores will merge one can roam data between a Windows 8.1 app and a Windows Phone 8.1 app, just set the same app id to both apps in the store. If you want to find out when roaming data has been changed by someone else you need to listen to DataChanged. This fires if roaming data is change by another app:
applicationData.DataChanged += DataChangedHandler;

private async void DataChangedHandler(ApplicationData appData, object o)
{
    // Add code
}

RoamingStorageQuota

How much data can you roam? By calling RoamingStorageQuota you get the amount of data possible to roam. If you try to roam more data than RoamingStorageQuota specifies the system stop replication the data until it below the limit again. The normal amount of data possible to roam is 100kb.

var quota = applicationData.RoamingStorageQuota;

Settings

The settings saving is also the same as Windows 8.1. Instead of targeting LocalStorage it is possible to target LocalSettings, there is also a RoamingSettings. This works the same as folders does, local saves locally and roaming saves to the cloud. How do settings work then? Quite easy actually, just fetch the settings and save:

var roamingSettings = ApplicationData.Current.RoamingSettings;
roamingSettings.Values["MySetting"] = "Hello World";

In addition to save text to a setting one can save a composite value. This is a setting which contains several settings:

var composite = new ApplicationDataCompositeValue();
composite[settingName1] = 1;
composite[settingName2] = "world";
roamingSettings.Values["MyCompositeSetting"] = composite;

It is also possible to create containers in the settings. This for making it easier to structure the settings. Example of a container:

var container = localSettings.CreateContainer("exampleContainer", ApplicationDataCreateDisposition.Always);
if (localSettings.Containers.ContainsKey("exampleContainer"))
{
    localSettings.Containers["MyContainer"].Values["MySetting"] = "Hello Windows";
}

If you use RoamingSettings changes can also be detected using the

applicationData.DataChanged += DataChangedHandler;

Version

If you´re saving data and update your app you might need to use versioned data. Versioning enables you to change the application data format used in a future release of your app without causing compatibility problems with previous releases of your app. The app checks the version of the data in the data store, and if it is less than the version the app expects, the app should update the application data to the new format and update the version. The version start at zero and can be obtain by checking

var version = ApplicationData.Current.Version;

if the version is lower than the expected to some converting and set the version to the correct one

ApplicationData.Current.SetVersionAsync(1, SetVersionHandler);

Summary

It is very nice to have the same data handling as in Windows 8.1. It is now possible to roam, save settings etc. This makes it easier to develop and share code between Windows Phone 8.1 and Windows 8.1 projects.