Improve Xamarin Forms App UX by Data Caching

When developing a mobile app persisting data is important, why? Because a mobile app is not a web app, it shouldn’t depend on having a reliable internet connection 100% of the time. For example, when you open a mobile app to see the list of transactions if you don’t have internet you will only see an empty screen with “There is no internet connection error” message. Won’t it be a better user experience if you could see the latest data cached?

In Xamarin Forms there are some options we can use to do data caching:

  • Use a local database like SQLite or Realm
  • Use a caching library for basic use cases.

In this article, I’m going to show you how to do data caching by using the Monkey-Cache library by James Montemagno.

Let’s explore MonkeyCache

” The goal of Monkey Cache is to enable developers to easily cache any data for a limited amount of time.”

Setup

Barrel.ApplicationId = “your_unique_name_here”;

Save data

Barrel.Current.Add(key, data, expireIn);

Retrieve data

Barrel.Current.Get<Type of Data you want to get>(url);

Remove data

Barrel.Current.EmptyAll();

Let’s use it

1.Install the MonkeyCache.FileStore package

2.Create an ApiManager class to handle your requests and assign an ApplicationId to the cache library

public interface IApiManager
{
Task<IEnumerable<MakeUp>> GetMakeUpsAsync();
}
using System;
namespace CachingDataSample.Services
{
public class ApiManager: IApiManager
{
public ApiManager()
{
Barrel.ApplicationId = "CachingDataSample";
}
public async Task<IEnumerable<MakeUp>> GetMakeUpsAsync()
{
}
}
}

3.Send the API request and store in cache the data response

If there’s no internet connection and the data cached has not expired the method will return the data in the cache, if not it will do an API request and will store the JSON response by using the MonkeyCache library.

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Threading.Tasks;
using Acr.UserDialogs;
using CachingDataSample.Models;
using MonkeyCache.FileStore;
using Newtonsoft.Json;
using Xamarin.Essentials;
namespace CachingDataSample.Services
{
public class ApiManager: IApiManager
{
public ApiManager()
{
Barrel.ApplicationId = "CachingDataSample";
}
const string url = "https://makeup-api.herokuapp.com/api/v1/products.json";
public async Task<IEnumerable<MakeUp>> GetMakeUpsAsync()
{
try
{
if (Connectivity.NetworkAccess != NetworkAccess.Internet &&
!Barrel.Current.IsExpired(key: url))
{
await Task.Yield();
UserDialogs.Instance.Toast("Please check your internet connection", TimeSpan.FromSeconds(5));
return Barrel.Current.Get<IEnumerable<MakeUp>>(key: url);
}
var client = new HttpClient();
var json = await client.GetStringAsync(url);
var makeUps = JsonConvert.DeserializeObject<IEnumerable<MakeUp>>(json);
//Saves the cache and pass it a timespan for expiration
Barrel.Current.Add(key: url, data: makeUps, expireIn: TimeSpan.FromDays(1));
return makeUps;
}
catch (Exception ex)
{
//Handle exception here
}
return null;
}
}
}

Extra libraries used:

NOTE: If you want to see better options to show the internet connection error message, you can check this article.

4.Call the service in your ViewModel

using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Input;
using CachingDataSample.Models;
using CachingDataSample.Services;
using Xamarin.Forms;
namespace CachingDataSample.ViewModels
{
public class MakeUpPageViewModel: INotifyPropertyChanged
{
protected IApiManager ApiManager = new ApiManager();
public ICommand GetMakeUpsCommand { get; set; }
public ObservableCollection<MakeUp> MakeUps { get; set; }
public bool IsRunning { get; set; }
public MakeUpPageViewModel()
{
GetMakeUpsCommand = new Command(async () => await GetMakeUps());
GetMakeUpsCommand.Execute(null);
}
async Task GetMakeUps()
{
IsRunning = true;
var result = await ApiManager.GetMakeUpsAsync();
if (result != null)
MakeUps = new ObservableCollection<MakeUp>(result);
IsRunning = false;
}
public event PropertyChangedEventHandler PropertyChanged;
}
}

5.Show the elements in your XAML

<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="CachingDataSample.Views.MakeUpPage"
Title="MakeUps">
<StackLayout VerticalOptions="FillAndExpand">
<ActivityIndicator HorizontalOptions="Center"
IsRunning="{Binding IsRunning}"
Color="Gray"/>
<ListView ItemsSource="{Binding MakeUps}"
RowHeight="100"
HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ImageCell ImageSource="{Binding Image_link}"
Text="{Binding Name}"
Detail="{Binding Description}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage>

The result:

That’s all for now! If you want to know more information about this great library, you can check more information here.

Check the full source code here.

Happy coding!

You may also like

2 Comments