Introduction
Firstly, let me tell you that I am not going to describe here something out of the blue, there are many articles available on the internet about how to save data in isolated storage in Widows Phone 8.1, but what I was trying to achieve was not easily available and I had to find some mechanism to make it work.
I came to know that in Windows Phone 8.1 RT Microsoft has introduced many new features and changes in the Windows Phone 8.1. Isolated Storage is one of the crucial features that has completely changed in Windows Phone 8.1.
In this article, I am going to describe what has changed and how to achieve the same functionality in Windows Phone 8.1 RT.
Background
In my previous Windows Phone 8 apps, I have one object called GameScore
that contains the Score of the Game and as when the game progresses and reaches different labels, it saves that score. And the new GameScore
Object we save in IsolatedStorage
.
But when I was trying to implement the same concept in Windows Phone 8.1 RT, I was surprised that the entire concept has changed and I had to find a different mechanism to achieve the same. This article is all about how to achieve that.
Given below is the visual representation of what I am going to achieve in Windows Phone 8.1.
Using the Code
Please download the source code and run for better understanding of this article.
Let me first tell you what I did in Windows Phone 8.
In Windows Phone 8, I have a class:
public class GameScore
{
public string Date {get;set;}
public int Score {get;set;}
public string Time {get;set;}
}
When the game gets over, we need to save the game score to an object here GameScore
in IsolatedStorage
. By using a backgroundtask
, we have achieved this in here is the code…
private void SaveGameScoreAsync(GameScore gameScore)
{
GameScore DataLists = gameScore;
IsolatedStorageSettings localStorage = IsolatedStorageSettings.ApplicationSettings;
if (!localStorage.Contains("GameData"))
{
IsoScoresSettings.Add(DataLists);
localStorage.Add("GameData", IsoScoresSettings);
}
else
{
List<GameScore> GameScoresCollections = new List<GameScore>();
GameScoresCollections = IsolatedStorageSettings.ApplicationSettings["GameData"]
as List<GameScore>;
GameScoresCollections.Add(DataLists);
localStorage["GameData"] = GameScoresCollections;
}
localStorage.Save();
}
So by this mechanism, we can save the GameScore
in the IsolatedStorage
, of course there are many mechanisms available in Window Phone 8
, but it was the most commonly used among the developers to save some settings in IsolatedStorage
, however that’s not the discussion of the article.
In Windows Phone 8.1 RT, instead of IsolatedStorage
we can use LocalFolder
to store data in the phone.
I will use ApplicationData.Current.LocalFolder
and DataContractSeriliazer
to achieve the desired functionality as Windows Phone 8.
As you can see in the MainPage.xaml.cs, I have written:
private const string JSONFILENAME = "data.json";
This data.json will be a file in which we will write, and save game related data.
Then, I will create a class GameScore
, similarly as Windows Phone 8.
public class GameScore
{
public string Id {get;set;}
public int Score {get;set;}
public string Time {get;set;}
}
Let’s create a GameScore
Object in MainPage.xaml.cs.
private List<GameScore> BuildGameScore()
{
var myScore = new List< GameScore >();
myScore.Add(new GameScore () { Id = "1", Score = 100, Time = "220"});
myScore.Add(new GameScore () { Id = "2", Score = 200, Time = "500"});
myScore.Add(new GameScore () { Id = "3", Score = 300, Time = "880"});
myScore.Add(new GameScore () { Id = "4", Score = 400, Time = "250"});
return myScore;
}
Now what I need to do? I have to write two methods, one method that will write data in the data.json file and one method to read the data.
The Write
method is writeJsonAsync
, and read method is readJsonAsync
.
private async Task writeJsonAsync()
{
var myGameScore = BuildGameScore();
var serializer = new DataContractJsonSerializer(typeof(List<GameScore>));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
JSONFILENAME,
CreationCollisionOption.ReplaceExisting))
{
serializer.WriteObject(stream, myGameScore);
}
resultTextBlock.Text = "Write succeeded";
}
private async Task readJsonAsync()
{
string content = String.Empty;
List<GameScore> ListGameScore = new List<GameScore>();
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);
using (StreamReader reader = new StreamReader(myStream))
{
content = await reader.ReadToEndAsync();
}
resultTextBlock.Text = content;
}
Now as you can see, that there are two Button Clicks
event in the XAML:
Now, I implement two button click events in code behind.
private async void readButton_Click(object sender, RoutedEventArgs e)
{
await readJsonAsync();
}
private async void writeButton_Click(object sender, RoutedEventArgs e)
{
await writeJsonAsync();
}
If I run the app and firstly click on Write
one message displayed in the UI:
Write succeeded
So now our task is to test this, click on Read
button.
The data stored in the data.json will be displayed in the UI.
So our primary task we have achieved, we have written data in the file and read it perfectly.
But that's not our motto, we want to write data in the file and update the file without losing our previous data.
So to achieve this, first we need to write a method in GameScore
class that will do our job.
public static List<GameScore> ConvertToGameScoreItems(string json)
{
List<GameScore> rsp = new List<GameScore>();
try
{
DataContractJsonSerializer serializer = new
DataContractJsonSerializer(typeof(List<GameScore>));
using (MemoryStream ms = new MemoryStream(Encoding.Unicode.GetBytes(json)))
{
rsp = serializer.ReadObject(ms) as List<GameScore>;
}
}
catch(Exception ex) { }
return rsp;
}
So what does this jsonserializer do? This will read all the data stored in the json
file and convert it to List<GameScore>
object. So in this way, we will not lose our data.
But how to use this? In our MainPage.xaml.cs, we will write one more task and will assign that to one more Button_Click event
to a different button - Write-Read
.
private async Task AddEntryIntoJsonAsync()
{
string content = String.Empty;
List<GameScore> ListGameScore = new List<GameScore>();
var myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);
using (StreamReader reader = new StreamReader(myStream))
{
content = await reader.ReadToEndAsync();
}
ListGameScore = GameScore.ConvertToGameScoreItems(content);
ListGameScore.Add(new GameScore() { Id = "11", Score = 545, Time = "874"});
var serializer = new DataContractJsonSerializer(typeof(List<GameScore>));
using (var stream = await ApplicationData.Current.LocalFolder.OpenStreamForWriteAsync(
JSONFILENAME,
CreationCollisionOption.ReplaceExisting))
{
serializer.WriteObject(stream, ListGameScore);
}
myStream = await ApplicationData.Current.LocalFolder.OpenStreamForReadAsync(JSONFILENAME);
using (StreamReader reader = new StreamReader(myStream))
{
content = await reader.ReadToEndAsync();
}
resultTextBlock.Text = content;
}
and assign this to one more Button_Click
event.
private async void readWriteButton_Click(object sender, RoutedEventArgs e)
{
await AddEntryIntoJsonAsync();
}
So by this ConvertToGameScoreItems
implemented in GameScore
class, I have achieved what I was doing in Windows Phone 8.
This object can be used to display the Game score in the UI. But that’s not the scope of this article.
Summary
In this article, I showed how to use Json and serializer to save, load and update the json file.
I hope you like this article, in the next article I plan to concentrate on some new features of Windows phone 8.1 with some more practical usage examples.
History
This is my first draft, if there are any typos or mistakes, please reply in the comments sections and I will definitely update this article.