[Xamarin.Forms] Backgrounding y persistencia de datos

Save-01-WFIntroducción

En dispositivos móviles contamos con una aplicación en primer plano. Cuando cambiamos de aplicación, si el usuario vuelve a la anterior, normalmente las aplicaciones vuelven a la última pantalla en la que se encontraba el usuario, con los datos e información que el usuario dejo. Todo listo y preparado para continuar. Un detalle que parece trivial pero que hoy día es necesario y esperado en cualquier aplicación.

Como desarrolladores debemos conocer el ciclo de vida de las aplicaciones móviles, la gestión y persistencia de información y como aplicar todo ese conocimiento para otorgar la mejor experiencia posible al usuario en cada plataforma.

En este artículo, vamos a aprender como realizar la persistencia de información de la aplicación en el ciclo de vida de la misma en Xamarin.Forms.

Eventos ciclo de vida

En Xamarin.Forms contamos con la clase Application donde establecemos el punto de entrada de la aplicación además de contar con métodos virtuales que podemos sobreescribir para gestionar el ciclo de vida de la aplicación:

  • OnSleep: Este evento se lanza cuando la aplicación pasa a background.
  • OnResume: Lanzado cuando la aplicación se resume después de estar en background.
protected override void OnStart()
{
    Debug.WriteLine ("OnStart");
}
protected override void OnSleep()
{
    Debug.WriteLine ("OnSleep");
}
protected override void OnResume()
{
    Debug.WriteLine ("OnResume");
}

Properties Dictionary

Desde la llegada de Xamarin.Forms 1.3 tenemos a nuestra disposición Application.Current.Properties. Ideal para utilizar en la suspensión y reanudación de la aplicación. Estamos ante un Dictionary con un uso muy sencillo que se encarga automáticamente del almacenamiento de datos en local.

Guardar

Utilizando Application.Current.Properties bastará con crear una nueva clave y asignar el valor:

Application.Current.Properties ["value"] = 1;

Leer

Recuperamos el valor utilizando la clave:

if (Application.Current.Properties.ContainsKey("value"))
{
     var val = Convert.ToInt32(Application.Current.Properties["value"]);
}

NOTA: Importante resaltar que como con el trabajo de cualquier diccionario, debemos verificar previamente la existencia del valor dado la clave otorgada.

Eliminar

En caso de desear eliminar el valor, de nuevo utilizamos la clave:

if (Application.Current.Properties.ContainsKey("value"))
{
     Application.Current.Properties.Remove("value");
}

Detalles a tener en cuenta

Debemos tener en cuenta que:

  • El valor asignado a una clave solo se guardará cuando se realice la suspensión de la aplicación (método OnSleep()). Es importante tener este detalle en cuenta ya que ante un cierre inesperado o bien en depuración al parar la misma, no guardaremos el valor al no realizarse la suspensión.
  • Al trabajar con un diccionario podemos guardar practicamente cualquier cosa, incluso entidades de clases propias que se serializarán.
  • Con Xamarin.Forms 1.4 se añadió un método adicional llamado SavePropertiesAsync() que podemos utilizar para guardar programáticamente cualquier cambio.

Persistencia de datos en Apps Xamarin.Forms

Para probar la persistencia de información junto al ciclo de vida de la aplicación vamos a crear un ejemplo Xamarin.Forms sencillo donde tendremos un formulario básico y guardaremos y recuperaremos la información al suspender y reanudar la aplicación.

Creamos la interfaz básica a utilizar:

<Grid
    VerticalOptions="Start">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="100" />
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Label Grid.Column="0" Grid.Row="0" Text="First Name" VerticalOptions="End" />
    <Entry Grid.Column="1" Grid.Row="0" Text="{Binding FirstName, Mode=TwoWay}" />
</Grid>

El resultado:

Nuestra UI
Nuestra UI

En la viewmodel la propiedad bindeada:

private string _firstName;

public string FirstName
{
     get { return _firstName; }
     set
     {
          _firstName = value;
          RaisePropertyChanged();
     }
}

En la clase Application contamos con los métodos para gestionar el ciclo de vida de la aplicación. Como hemos visto, contamos con el método OnSleep() lanzado cuando la aplicación pasa a segundo plano. En este punto accederemos a la propiedad FirstName bindeada a la UI de la viewmodel y la guardaremos utilizando Properties Dictionary:

Application.Current.Properties["FirstName"] = viewModel.FirstName;   

Cuando la aplicación se resume, se lanza el evento OnResume(). En este punto verificamos la existencia de la propiedad FirstName y en caso de existir, la asignamos en nuestra viewmodel:

if (Application.Current.Properties.ContainsKey("FirstName"))
{
     var firstName = (string)Application.Current.Properties["FirstName"];
  
     viewModel.FirstName = firstName;
}

Podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Más información