Administración de la configuración

Nota:

Este libro se publicó en la primavera de 2017 y no se ha actualizado desde entonces. Hay mucho en el libro que sigue siendo valioso, pero algunos de los materiales están obsoletos.

La configuración permite la separación de datos que configura el comportamiento de una aplicación desde el código, lo que permite cambiar el comportamiento sin volver a generar la aplicación. Hay dos tipos de configuración: la configuración de la aplicación y la configuración de usuario.

La configuración de la aplicación son datos que crea y administra una aplicación. Puede incluir datos como puntos de conexión fijos de servicio web, claves de API y estado en tiempo de ejecución. La configuración de la aplicación está vinculada a la existencia de la aplicación y solo es significativa para esa aplicación.

La configuración del usuario es la configuración personalizable de una aplicación que afecta al comportamiento de la aplicación y no requiere un reajuste frecuente. Por ejemplo, una aplicación podría permitir al usuario especificar dónde recuperar datos y cómo mostrarlos en la pantalla.

Xamarin.Forms incluye un diccionario persistente que se puede usar para almacenar datos de configuración. Se puede acceder a este diccionario mediante la propiedad Application.Current.Properties y los datos que se colocan en él se guardan cuando la aplicación entra en un estado de suspensión y se restauran cuando la aplicación se reanuda o se inicia de nuevo. Además, la clase Application también tiene un método SavePropertiesAsync que permite a una aplicación guardar su configuración cuando sea necesario. Para obtener más información sobre este diccionario, vea Diccionario de propiedades.

Una desventaja de almacenar datos mediante el diccionario persistente Xamarin.Forms es que no se enlazan fácilmente a los datos. Por lo tanto, la aplicación móvil eShopOnContainers usa la biblioteca Xam.Plugins.Settings, disponible en NuGet. Esta biblioteca proporciona un enfoque coherente, con seguridad de tipos y multiplataforma para conservar y recuperar la configuración de las aplicaciones y los usuarios, al tiempo que utiliza la administración de configuración nativa de cada plataforma. Además, es sencillo usar el enlace de datos para acceder a los datos de configuración expuestos por la biblioteca.

Nota:

Aunque la biblioteca Xam.Plugin.Settings puede almacenar la configuración de la aplicación y del usuario, no distingue entre los dos.

Creación de una clase Settings

Al usar la biblioteca Xam.Plugins.Settings, se debe crear una sola clase estática que contendrá la aplicación y la configuración de usuario requerida por la aplicación. En el ejemplo de código siguiente se muestra la clase Settings en la aplicación móvil eShopOnContainers:

public static class Settings  
{  
    private static ISettings AppSettings  
    {  
        get  
        {  
            return CrossSettings.Current;  
        }  
    }  
    ...  
}

La configuración se puede leer y escribir a través de la API ISettings, que proporciona la biblioteca Xam.Plugins.Settings. Esta biblioteca proporciona un singleton que se puede usar para acceder a la API, CrossSettings.Current, y la clase de configuración de una aplicación debe exponer este singleton a través de una propiedad ISettings.

Nota:

El uso de directivas para los espacios de nombres Plugin.Settings y Plugin.Settings.Abstractions debe agregarse a una clase que requiera acceso a los tipos de biblioteca Xam.Plugins.Settings.

Agregar una configuración

Cada configuración consta de una clave, un valor predeterminado y una propiedad. En el ejemplo de código siguiente se muestran los tres elementos de una configuración de usuario que representa la dirección URL base de los servicios en línea a los que se conecta la aplicación móvil eShopOnContainers:

public static class Settings  
{  
    ...  
    private const string IdUrlBase = "url_base";  
    private static readonly string UrlBaseDefault = GlobalSetting.Instance.BaseEndpoint;  
    ...  

    public static string UrlBase  
    {  
        get  
        {  
            return AppSettings.GetValueOrDefault<string>(IdUrlBase, UrlBaseDefault);  
        }  
        set  
        {  
            AppSettings.AddOrUpdateValue<string>(IdUrlBase, value);  
        }  
    }  
}

La clave siempre es una cadena const que define el nombre de clave, con el valor predeterminado para la configuración que es un valor estático de solo lectura del tipo necesario. Proporcionar un valor predeterminado garantiza que un valor válido esté disponible si se recupera un ajuste no establecido.

La propiedad estática UrlBase usa dos métodos de la API ISettings para leer o escribir el valor de configuración. El método ISettings.GetValueOrDefault se usa para recuperar el valor de una configuración del almacenamiento específico de la plataforma. Si no se define ningún valor para la configuración, su valor predeterminado se recupera en su lugar. Del mismo modo, el método ISettings.AddOrUpdateValue se usa para conservar el valor de una configuración en el almacenamiento específico de la plataforma.

En lugar de definir un valor predeterminado dentro de la clase Settings, la cadena UrlBaseDefault obtiene su valor de la clase GlobalSetting. En el ejemplo de código siguiente se muestra la propiedad BaseEndpoint y el método UpdateEndpoint en esta clase:

public class GlobalSetting  
{  
    ...  
    public string BaseEndpoint  
    {  
        get { return _baseEndpoint; }  
        set  
        {  
            _baseEndpoint = value;  
            UpdateEndpoint(_baseEndpoint);  
        }  
    }  
    ...  

    private void UpdateEndpoint(string baseEndpoint)  
    {  
        RegisterWebsite = string.Format("{0}:5105/Account/Register", baseEndpoint);  
        CatalogEndpoint = string.Format("{0}:5101", baseEndpoint);  
        OrdersEndpoint = string.Format("{0}:5102", baseEndpoint);  
        BasketEndpoint = string.Format("{0}:5103", baseEndpoint);  
        IdentityEndpoint = string.Format("{0}:5105/connect/authorize", baseEndpoint);  
        UserInfoEndpoint = string.Format("{0}:5105/connect/userinfo", baseEndpoint);  
        TokenEndpoint = string.Format("{0}:5105/connect/token", baseEndpoint);  
        LogoutEndpoint = string.Format("{0}:5105/connect/endsession", baseEndpoint);  
        IdentityCallback = string.Format("{0}:5105/xamarincallback", baseEndpoint);  
        LogoutCallback = string.Format("{0}:5105/Account/Redirecting", baseEndpoint);  
    }  
}

Cada vez que se establece la propiedad BaseEndpoint, se llama al método UpdateEndpoint. Este método actualiza una serie de propiedades, todas las cuales se basan en la configuración de usuario UrlBase proporcionada por la clase Settings que representa distintos puntos de conexión a los que se conecta la aplicación móvil eShopOnContainers.

Enlace de datos a la configuración del usuario

En la aplicación móvil eShopOnContainers, SettingsView expone dos configuraciones de usuario. Estas opciones permiten la configuración de si la aplicación debe recuperar datos de microservicios implementados como contenedores Docker o si la aplicación debe recuperar datos de servicios ficticios que no requieren conexión a Internet. Al elegir recuperar datos de microservicios en contenedores, se debe especificar una dirección URL de punto de conexión base para los microservicios. En la figura 7-1 se muestra SettingsView cuando el usuario ha elegido recuperar datos de microservicios en contenedores.

User settings exposed by the eShopOnContainers mobile app

Figura 7-1: Configuración del usuario expuesta por la aplicación móvil eShopOnContainers

El enlace de datos se puede usar para recuperar y establecer la configuración expuesta por la clase Settings. Esto se logra mediante controles en el enlace de vista para ver las propiedades del modelo que, a su vez, acceden a las propiedades de la clase Settings y generan una notificación de cambio de propiedad si el valor de configuración ha cambiado. Para obtener información sobre cómo la aplicación móvil eShopOnContainers construye modelos de vista y los asocia a vistas, consulte Creación automática de un modelo de vista con un localizador de modelos de vista.

En el ejemplo de código siguiente se muestra el control Entry del valor SettingsView que permite al usuario escribir una dirección URL de punto de conexión base para los microservicios en contenedores:

<Entry Text="{Binding Endpoint, Mode=TwoWay}" />

Este control Entry se enlaza a la propiedad Endpoint de la clase SettingsViewModel utilizando un enlace bidireccional. En el código de ejemplo siguiente se muestra la propiedad Endpoint:

public string Endpoint  
{  
    get { return _endpoint; }  
    set  
    {  
        _endpoint = value;  

        if(!string.IsNullOrEmpty(_endpoint))  
        {  
            UpdateEndpoint(_endpoint);  
        }  

        RaisePropertyChanged(() => Endpoint);  
    }  
}

Cuando se establece la propiedad Endpoint, se llama al método UpdateEndpoint, siempre que el valor proporcionado sea válido y se genere la notificación de cambio de propiedad. El siguiente ejemplo de código muestra el método UpdateEndpoint:

private void UpdateEndpoint(string endpoint)  
{  
    Settings.UrlBase = endpoint;  
}

Este método actualiza la propiedad UrlBase de la clase Settings con el valor de dirección URL del punto de conexión base especificado por el usuario, lo que hace que se conserve en el almacenamiento específico de la plataforma.

Cuando se navega a SettingsView, se ejecuta el método InitializeAsync de la clase SettingsViewModel. El siguiente ejemplo de código muestra este método:

public override Task InitializeAsync(object navigationData)  
{  
    ...  
    Endpoint = Settings.UrlBase;  
    ...  
}

El método establece la propiedad Endpoint en el valor de la propiedad UrlBase de la clase Settings. El acceso a la propiedad UrlBase hace que la biblioteca Xam.Plugins.Settings recupere el valor de configuración del almacenamiento específico de la plataforma. Para obtener información sobre cómo se invoca el método InitializeAsync, vea pasar parámetros durante la navegación.

Este mecanismo garantiza que cada vez que un usuario navega a SettingsView, la configuración de usuario se recupera del almacenamiento específico de la plataforma y se presenta a través del enlace de datos. A continuación, si el usuario cambia los valores de configuración, el enlace de datos garantiza que se conserven inmediatamente en el almacenamiento específico de la plataforma.

Resumen

La configuración permite la separación de datos que configura el comportamiento de una aplicación desde el código, lo que permite cambiar el comportamiento sin volver a generar la aplicación. La configuración de la aplicación son datos que una aplicación crea y administra, y la configuración del usuario es la configuración personalizable de una aplicación que afecta al comportamiento de la aplicación y no requiere un reajuste frecuente.

La biblioteca Xam.Plugins.Settings proporciona un enfoque coherente, seguro para tipos y multiplataforma para conservar y recuperar la configuración de la aplicación y el usuario, y el enlace de datos se puede usar para acceder a la configuración creada con la biblioteca.