Build an Open Data App – Part 3: Storing and Retrieving the Data

The next step in putting the app together is to implement local storage of the dataset. The reason for this is two fold:

  1. If your user is not connected to the internet (on the subway with a phone, internet is down at home, etc.) you want them to still be able to use the app.
  2. If you don’t need to use their bandwidth, don’t.

Both of these points relate to respecting your user and put them front and center. With the app as we’re building it for now, we won’t be needing to update the list very often. The first step in this process is to save the data locally.

What we need to do first is replace a bit of code we wrote in the GetStations method in the last part of this series.

if (jsonString.Length > 0)
{
    var localFolder = ApplicationData.Current.LocalFolder;
    var file = await localFolder.CreateFileAsync(JsonFileName, CreationCollisionOption.ReplaceExisting);
            
    using (var writer = new StreamWriter(await file.OpenStreamForWriteAsync()))
    {
        writer.Write(jsonString);
    }

    try
    {
        var bikeStationsResponse = JsonConvert.DeserializeObject<bikestationresponse>(jsonString);
        BikeStations = bikeStationsResponse.Stations;
    }
    catch (Exception e)
    {
        int i = 9;
    }
}

You should recognize part of that code, and so should see where you need to replace things. If not, refer back to part 2 of this series. To support this, you’ll need to define JsonFileName, which is merely a string of the file name including extension (ie: DataFile.json). Ideally, you’ll extract the actual file creation and writing into its own method so you can call it at other times. Also, note in line 4 that one of the arguments is CreationCollisionOption.ReplaceExisitng. Be aware that this option will overwrite a file with the same name. As we want to replace old data with new, this is fine.

Now that we have a local version of the data, let’s set up the code so we’ll only get new data once a day.

StorageFile localDataFile;
try
{
    localDataFile = await ApplicationData.Current.LocalFolder.GetFileAsync(JsonFileName);
}
catch
{
    localDataFile = null;
}

if (localDataFile == null || (localDataFile != null && DateTime.Today.AddDays(-1) > localDataFile.DateCreated))
{
    jsonString = await GetBikeStationsFromServer(new Uri(BikeStationJsonUrlString, UriKind.Absolute));
}
else
{
    var stream = await localDataFile.OpenStreamForReadAsync();
    using (StreamReader streamReader = new StreamReader(stream))
    {
        jsonString = streamReader.ReadToEnd();
    }
}

The code above replaces the line containing GetBikeStationsFromServer in part 2’s code. As you can see, if the file doesn’t exist, or it’s more than a day old, we go to the server. Not the try catch around getting the file. Failing to find a file is an exception, it does not return null. Otherwise we use the local code. And since it all comes back to the string, we can safely extract the loading method as well.

Now that we’ve taken care of our data storage and retrieval, it’s time to move on to binding the data.

This entry was posted in .NET, Building an Open Data App, Open Data, Windows 8, Windows 8.x, Windows Phone. Bookmark the permalink.

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 )

Google photo

You are commenting using your Google 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 )

Connecting to %s