Persisting Data in Xamarin Forms (Part 1)

Data Persistence in Xamarin Forms

Part 1 – Property Lists

Hello everybody and welcome to my series on data persistence in Xamarin Forms. I frequently lurk various Facebook forums and stack overflow and repeatedly see the same questions being asked…

  • How can I store data on a device?
  • How should I store data on a device?
  • How can I use SQLite in Xamarin?
  • What’s the best way to store data in MVVM?

So I have decided to answer all of these questions and more in a series of blog posts. Today’s topic is the property list, this can be used to store small bits of data that might be useful to your app (such as first time user, last logged in date etc).

So before we get coding, lets first talk about the library we are going to be using Settings Plugin by James Montemagno. If you haven’t heard of James before, subscribe to his blog, follow him on twitter, listen to his podcasts and watch the xamarin show. James works for the Xamarin team and has made some amazing contributions to the platform, this guy is the authority of xamarin, go follow him now! Anyway the Settings Plugin allows you to store data on the device your app is running on. This plugin is cool because makes use of native functionality on each platform, storing data in NSUserDefaults on iOS and in the SharedPreferences on Android.

The use case of this plugin (as I mentioned earlier) is for saving 1 off data. You could use this plugin to store the following kinds of data:

  • Has the user ever used the app before?
  • Remember the users username
  • User preferences for controls
  • The base url of your api (so you can then change it without a new build)
  • Plus many more!

All of this data could be stored in a SQLite database, however this would require it’s own table and would be a massive hassle, using the app settings makes this process much easier. With SQLite in mind, here are some things you SHOULDN’T do with the app properties (don’t worry I’ll show you how to do these in my next blog):

  • To store lots of the same data (like objects)
  • To store data you are passing between views

So anyway, lets get into our project and learn how to persist data in the apps settings!

Project Setup

Start by creating a blank xamarin app and as always, make sure you are using .NET Standard.

Create project.png

Lets check our project is running first by building it (you’d be surprised how often brand new projects wont build). Now install Xam.Plugin.Settings into each of your projects (shared, ios , android).

install plugin.png

Now lets create the following:

  • A new folder in our shared project (called “Settings”
  • A new Interface file called “IAppSettings”
  • and a new Class file called “AppSettings”

The settings plugin has an interface called “ISettings” so we don’t want conflicts with our own interface!

Your project should now look like this, let’s have a look at Plugin.Settings and how to use it in our “AppSettings” class.

project setup.png

Inside the “AppSettings” class we need to add a property to access the app settings.

/// <summary>
/// App Settings Connection.
/// </summary>
private static ISettings _appSettings => CrossSettings.Current;

So this property allows us to access the local app settings (created by the plugin) and store / retrieve data. Lets try storing some data in the app settings! I’m going to store the base url for a server (so that we can change where our app is pointing to without a new build).

Start by defining a public property:

/// <summary>
/// Gets or Sets the Server Redirect URL
/// </summary>
public string RedirectUrl { get; set; }
view raw redirecturl.cs hosted with ❤ by GitHub

Now before we set this property, we will have a quick look at the methods we have access to from our ISettings connection. The 2 important methods are:

  • GetValueOrDefault
  • AddOrUpdateValue

GetValueOrDefault gets you a value from the app’s settings if it exists, otherwise it returns a default value (that is set in code).

AddOrUpdateValue sets the value in the app’s settings or updates it if it exists.

So simple so good, lets add these methods to the get/set of our property:

/// <summary>
/// Gets or Sets the Server Redirect URL
/// </summary>
public string RedirectUrl
{
get
{
return _appSettings.GetValueOrDefault("redirecturl", "http://www.alexduffell.wordpress.com/api");
}
set
{
_appSettings.AddOrUpdateValue("redirecturl", value);
}
}
view raw redirecturl2.cs hosted with ❤ by GitHub

At this point we are functionally there, if we add this property to our interface we can access the value and use the app properties! however we can do 1 better. You might notice an issue with the above code that could leave room for errors…

The key is not a constant, therefore you could misspell it somewhere introducing bugs to your code that are easily avoided. In the root namespace of your project create a new file called “Constants.cs”, In this file we are going to put static strings so that we can reference them all around our project without risking spelling mistakes causing issues.

I like to create constants classes for each section of my app (settings, strings, urls, colours etc) so that everything is more easily accessible. Here is my settings constant class:

public class SettingsConstants
{
public const string RedirectUrlKey = "redirecturl";
public const string RedirectUrlDefault = "http://www.alexduffell.wordpress.com/api";
}

Now lets update the setters using our new constants:

#region Redirect URL
private static readonly string RedirectUrlKey = SettingsConstants.RedirectUrlKey;
private static readonly string RedirectUrlDefault = SettingsConstants.RedirectUrlDefault;
/// <summary>
/// Gets or Sets the Server Redirect URL
/// </summary>
public string RedirectUrl
{
get
{
return _appSettings.GetValueOrDefault(RedirectUrlKey, RedirectUrlDefault);
}
set
{
_appSettings.AddOrUpdateValue(RedirectUrlKey, value);
}
}
#endregion Redirect URL

Now our implementation inside this class is complete, we can add our property to the app settings aswell as retrieve it. Let’s add it to our interface and try and access it through code!

If you haven’t already, make your AppSettings class inherit from your interface IAppSettings :

class AppSettings : IAppSettings
{
...
}

And add our property to the interface:

interface IAppSettings
{
/// <summary>
/// Gets or Sets the Server Redirect URL
/// </summary>
string RedirectUrl { get; set; }
}

Now we can access or set our property in code, let’s use it in code!

I’ve prepared an example for you, this can be found in the source code that comes with this project. But don’t fret, I’m going to walk through all of the code with you and show you exactly how you would use this in a real world, MVVM settings.

We’ll start with this XAML view, I want to be able to show the current value stored in the property list and to be able to update it on the screen.

Screen Shot 2018-08-14 at 14.16.40.png

Xaml:

<StackLayout VerticalOptions="Center" Padding="20,0">
<Label Text="Redirect Url Here" HorizontalOptions="Center"/>
<Button Text="Get Redirect Url"/>
<BoxView HeightRequest="20" Color="Transparent"/>
<Entry Placeholder="Update Redirect Url"/>
<Button Text="Update"/>
</StackLayout>

Lets now create a view model, I’ll post a basic template below and we will build it up!

Firstly add 2 new folders to your shared library:

  • Views
  • ViewModels

Inside the ViewModels folder add a new class called “MainPageViewModel.cs”, we will use this as our view model. Also make sure you rename the MainPage’s namespace so that it is inside the .Views namespace (we are doing this by the book!).

In your ViewModel, add the following namespaces (so you aren’t searching for them later):

using System;
using System.ComponentModel;
using System.Windows.Input;
using Xamarin.Forms;
using DataPersistence.Properties.Settings;

Make your ViewModel inherit from INotifyPropertyChanged, we will use this to update our view when properties change in the view model.

public class MainPageViewModel : INotifyPropertyChanged
{
...
}

When you do this, visual studio will shout at you and ask you to implement the interface methods, however instead of doing this.. copy my code instead!

#endregion OnCommand Methods
#region PropertyChanged Methods
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion PropertyChanged Methods

Now before we start using the settings plugin, let’s connect our ViewModel to our view. At this point our view model is functional and if we change a property inside it, thanks to INotifyPropertyChanged it will update the value in any views linked to the view model. In the XAML for the view, reference the ViewModels namespace and set the BindingContext of the View as the ViewModel:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:DataPersistence.Properties.Views"
xmlns:viewModels="clr-namespace:DataPersistence.Properties.ViewModels"
x:Class="DataPersistence.Properties.Views.MainPage">
<ContentPage.BindingContext>
<viewModels:MainPageViewModel/>
</ContentPage.BindingContext>
...
...
</ContentPage>

Now let’s pull our app settings into the view model:

#region Properties
private IAppSettings _appSettings;
#endregion Properties

Now we can access our app settings, let’s make some properties that our view can bind too so that it can get and set the value of our Redirect URL.

#region Properties
private string _redirectUrl;
public string RedirectUrl
{
get => _redirectUrl;
}
private string _updatedValue;
public string UpdatedValue
{
get
{
return _updatedValue;
}
set
{
if (!String.IsNullOrEmpty(value))
{
_updatedValue = value;
}
}
}
#endregion Properties

We can bind to these properties in our view, but we won’t just yet because theres still more to do! Lets add the final properties we need to our ViewModel, commands. These commands will be called when our buttons are pressed. We both need to add command properties and handler methods, add the following to your ViewModel:

#region Properties
public ICommand GetValueCommand { get; private set; }
public ICommand UpdateValueCommand { get; private set; }
#endregion Properties
#region OnCommand Methods
private void OnGetValue()
{
_redirectUrl = _appSettings.RedirectUrl;
OnPropertyChanged(nameof(RedirectUrl));
}
private void OnUpdateValue()
{
if (_appSettings.RedirectUrl != _updatedValue)
{
_appSettings.RedirectUrl = _updatedValue;
}
}
#endregion OnCommand Methods

This is all great but you may have noticed that we haven’t initialised our commands yet. If they were called, nothing would happen. Lets sort out the constructor of our ViewModel! Inside this constructor we want to do the following things:

  • Initialise our AppSettings class
  • Initialise our commands and set their handler methods
  • Set some default text for _redirectUrl since it will be null (and the label will be empty until it’s value is updated).
public MainPageViewModel()
{
_appSettings = new AppSettings();
GetValueCommand = new Command(OnGetValue);
UpdateValueCommand = new Command(OnUpdateValue);
_redirectUrl = "Press to get redirect url";
}

Now our ViewModel is finished! When the user asks for the RedirectUrl property, the view model will fetch it from the AppSettings class. When the user set’s the value of RedirectUrl the ViewModel will update this value (so long as it is not the same).

Lets add all of the binding to our ViewModel!

<StackLayout VerticalOptions="Center" Padding="20,0">
<Label Text="{Binding RedirectUrl}" HorizontalOptions="Center"/>
<Button Text="Get Redirect Url" Command="{Binding GetValueCommand}"/>
<BoxView HeightRequest="20" Color="Transparent"/>
<Entry Placeholder="Update Redirect Url" Text="{Binding UpdatedValue}"/>
<Button Text="Update" Command="{Binding UpdateValueCommand}"/>
</StackLayout>

Finally we can run the app! As you can see from the gif below, we can get the value stored in the app settings and set the value. If you kill the app, the new value still persists!

app settings demo.gif

This concludes Part 1 of Persisting Data in Xamarin Forms – Property Lists. If this post helped you, please consider commenting and sharing so more developers can persist their apps data in Xamarin Forms without getting a headache!

You can find the completed solution available on GitHub

You can find me on the following sites:

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