31 Days of Windows Phone | Day #15: Isolated Storage

This post is Day #15 in a series called the 31 Days of Windows Phone.

Yesterday, we talked about tombstoning our applications, so that they appear to be running in the background.  Today, I’m going to cover a great way to store your data locally on the phone, using Isolated Storage.

What Is Isolated Storage?

Isolated Storage is not a new concept.  It’s been used in Silverlight since version 2.  It’s basically a way to store data or files on the local file system.  It’s “isolated” because only your application has access to the data.  If you have two applications, and you want to share data between them, you’d better have some kind of cloud-based service that can share that data for you.  Applications will not have the ability to share, call, or interact with other applications on the device.

Settings vs. Files

There are two ways to store your data locally.  The first is through a library of name/value pairs.  This is called IsolatedStorageSettings.  The second way is through actual file and folder creation.  This is called IsolatedStorageFile.  The image below (courtesy of MSDN) helps illustrate this briefly, and then I will dive into examples of each.

isolatedstorage

IsolatedStorageSettings

For many purposes, this might be the only storage that you need.  IsolatedStorageSettings allows you to store name/value pairs in a dictionary (without ANY setup, mind you), that you can retrieve later.  This data is persisted across application stop/start, powering the phone off, etc.  It’s there until you remove it, or the user uninstalls your application.  One important thing to remember is that you can’t retrieve a value until it’s been added to the library.  In each of my examples, you’re going to see code that checks to see if the value exists first, before retrieving it.  Here’s an example of the code you’d need to save a user’s preference for receiving email updates from your application.  I have one CheckBox that allows a user to decide, and events that store that value to IsolatedStorage.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO.IsolatedStorage;

namespace Day15_IsolatedStorage
{
	public partial class MainPage : PhoneApplicationPage
	{
		IsolatedStorageSettings settings = IsolatedStorageSettings.ApplicationSettings;
		
		// Constructor
		public MainPage()
		{
			InitializeComponent();
			InitializeSettings();
		}

		private void InitializeSettings()
		{
			if (settings.Contains("emailFlag"))
			{
				EmailFlag.IsChecked = (bool)settings["emailFlag"];
			}
			else settings.Add("emailFlag", false);
		}

		private void EmailFlag_Unchecked(object sender, RoutedEventArgs e)
		{
			settings["emailFlag"] = false;
		}

		private void EmailFlag_Checked(object sender, RoutedEventArgs e)
		{
			settings["emailFlag"] = true;
		}
	}
}

As you can see, this is incredibly simple.  Here’s a few things to remember:

  1. Trying to retrieve a value from IsolatedStorageSettings will throw an error if it hasn’t already been created.  Make sure you initialize your settings, or ALWAYS check the .Contains property first.
  2. You can save anything you want in the Settings.  I saved a boolean value in my example, but you could also save a Customer object, or any other else you can come up with.
  3. Remember that you have to explicitly cast your data when you retrieve it.  You’ll notice that I have to cast my bool value before I can use it.  You’re saving the object, but the storage does NOT save the type.  That’s up to you when you want to use it again.
  4. Setting a value is the same as adding a value to the library.  The “settings.Add()” statement is actually unnecessary, but I added it so that you could see the syntax.

So that’s about it.  IsolatedStorageSettings is pretty straightforward.  Save name/value pairs with very little actual code.  Creating and saving files is a little more complicated, but still surprisingly simple.  Let’s take a look at that now.

IsolatedStorageFile

Using IsolatedStorageFile is the mechanism you can use for storing actual FILES on the user’s device.  In my example, I’m going to create a text file in a subdirectory, and then retrieve the contents of that file.  We have the ability to create and delete folders, subfolders, and files.  This is going to seem like a TON more code, but it’s actually pretty simple.  We’re creating a new IsolatedStorageFile object, and then writing it to the drive using an IsolatedStorageFileStream.  I’ve added comments to my code inline, so that you can see what is happening a little easier.  I have two events, one that saves the file, and one that reads it:

using System.IO.IsolatedStorage;
using System.IO;

private void SaveButton_Click(object sender, RoutedEventArgs e)
{
	//Obtain a virtual store for application
	IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication();

	//Create new subdirectory
	fileStorage.CreateDirectory("textFiles");

	//Create a new StreamWriter, to write the file to the specified location.
	StreamWriter fileWriter = new StreamWriter(new IsolatedStorageFileStream("textFiles\newText.txt", FileMode.OpenOrCreate, fileStorage));
	//Write the contents of our TextBox to the file.
	fileWriter.WriteLine(writeText.Text);
	//Close the StreamWriter.
	fileWriter.Close();
}

private void GetButton_Click(object sender, RoutedEventArgs e)
{
	//Obtain a virtual store for application
	IsolatedStorageFile fileStorage = IsolatedStorageFile.GetUserStoreForApplication();
	//Create a new StreamReader
	StreamReader fileReader = null;

	try
	{
		//Read the file from the specified location.
		fileReader = new StreamReader(new IsolatedStorageFileStream("textFiles\newText.txt", FileMode.Open, fileStorage));
		//Read the contents of the file (the only line we created).
		string textFile = fileReader.ReadLine();

		//Write the contents of the file to the TextBlock on the page.
		viewText.Text = textFile;
		fileReader.Close();
	}
	catch
	{
		//If they click the view button first, we need to handle the fact that the file hasn't been created yet.
		viewText.Text = "Need to create directory and the file first.";
	}
}

This doesn’t seem like much of an amazing trick until you leave the application, come back, and try to load the file again (and it’s still there!).

So there you have it.  We have two simple storage mechanisms available to us in Windows Phone 7.  IsolatedStorageSettings and IsolatedStorageFile.  I’d be interested to hear the creative ways you are leveraging these storage structures in your application.  Please leave comments!

Download the Code

This example code incorporates both the Settings and File storage code shown above in one project.

download

17 thoughts on “31 Days of Windows Phone | Day #15: Isolated Storage

  1. now in mango release that is wp7.1 you can do it by socket programing using tcp protocol. i did it and was able to communicate between pc and emulator.

  2. Thanks for your postings this month.

    I wrote a small app that saves data to isolated storage. The question now is, how do I back up the file from the phone to my PC? Also, Can I write data to the phones isolated storage from my PC? What I want to do is to popluate a file on the phone with data I have on the pc.

  3. Russell,

    In order to get data off of a phone, and onto a computer, you're going to need to transport that data via web services. There is NO mechanism to transport data from a phone-to-PC sync.

  4. That sux. Although I do have an idea that MIGHT work. Would it be possible to deploy an app on the users PC that your app can talk to over WiFi or possibly over USB? The actual sync action would probably have to be initiated from the app on the phone. Maybe a web service running on the new IIS Express? Or perhaps have the app be able to email the file as an attachment? It may not even be possible. Just thinking out loud about possible solutions for syncing data back to the users PC. I have a simple ham radio app that runs on .net compact framework that I'd really like to port to wp7 but to be truly useful to the ham radio community there really needs to be a way to get files from the app to the users PC. Currently the app exports it's data to a file in the devices My Documents folder which can be reached from Windows Explorer on the PC when the mobile device is attached to USB.

  5. Hi Bryan,
    I did just what you were "Thinking out load". I wrote a web service that talks to my phone. I now can sync my data from the phone to my PC via the web service.

    This works on the emulator but I have yet to port it over to my real phone. I have not yet forked over the $100 bucks to be able to deploy my app to the phone. Hopefully, the web service will work for real just like it does on the emulator.

  6. I figured a web service could be done. I'm just not sure how practical that would be considering the very limited user base, ham radio operators, the app I'm wanting to write would have. I wonder if it's possible for an app to save a file to it's isolated storage and then upload that file to a service like SkyDrive or even DropBox. That would make it relatively easy for the user to then download the file onto their PC.

  7. This may be obvious, but while you are debugging with the emulator your settings will exist from run to run. When you want to test a completely fresh install of your app, uninstall it from the emulator (click and hold the app icon until the menu option pops up for "uninstall") which will erase all your settings.

  8. I knew from the start if I left a woman I really loved — the Great Society — in order to fight that bitch of a war in Vietnam then I would lose everything at home. My hopes my dreams.

  9. It is hard to believe that a man is telling the truth when you know that you would lie if you were in his place.

  10. Pingback: Getting ready for the Windows Phone 7 Exam 70-599 (Part 1)

  11. Pingback: Windows Phone 7-8 | Isolated Storage « Ahmet Müngen

  12. Pingback: Rajen's Technical Tidbits Storage on Windows 8 and Windows Phone - Rajen's Technical Tidbits

  13. You made my day with these examples. Perfect.

  14. hey jeff you blog has helped me alot! i was wondering if the same rule applies if i wanted to save multiple textbox information to a single file for instance filing out a form? and is there a difference in your examples that i need i want to display the contents in the order that it was filled out in a textbox thanks in advance!

  15. We have an app that uses about 100MB of isolated storage. In our code we use:

    IsolatedStorageSettings.ApplicationSettings[name] = xmlInfo;
    IsolatedStorageSettings.ApplicationSettings.Save();

    xmlinfo is the seriaized object.

    One object that gets serialized is around 44MB. At this size the save statement errors with an out of memory error. The save statement seems kind of optional. The app saves the data whether the save statement is called or not. The difference that I notice is that the save statment writes to disk immediately, where as without the save, writing to disk doesn’t happen until you exit the app. I notice in your example that you do not use a save. What’s your thought on the need for the save statement. thanks rr

  16. A little bit more info on my previous statement. The error that I receive happens on the IsolatedStorageSettings.ApplicationSettings.Save() statement. thanks.

  17. Thank you so much for these tutorials! I’m a Graphic Designer and this kind of information is invaluable. Saves me from begging my Dev buddies for help😀

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s