Compartir a través de


Migración de datos desde el diccionario de propiedades de la aplicación de Xamarin.Forms a preferencias de .NET MAUI

Xamarin.Forms tiene un diccionario Properties que se puede usar para almacenar datos y al que se accede mediante la propiedad Application.Current.Properties. Este diccionario usa una clave string y almacena un valor object. Los valores del diccionario se guardan en el dispositivo cuando una aplicación está en pausa o apagada, y se cargan cuando se reinicia o se devuelve una aplicación desde segundo plano. Para obtener más información sobre el diccionario de propiedades, consulta Diccionario de propiedades.

Al migrar una aplicación de Xamarin.Forms que almacena datos en el diccionario de propiedades de la aplicación a .NET MAUI, debes migrar estos datos a las preferencias de .NET MAUI. Esto se puede lograr con la clase LegacyApplication y las clases auxiliares, que se presentan en este artículo. Esta clase permite que tu aplicación de .NET MAUI en Android, iOS y Windows lea datos del diccionario de propiedades de la aplicación que se creó con una versión anterior de Xamarin.Forms de tu aplicación. Para obtener más información sobre las preferencias de .NET MAUI, consulta Preferencias.

Importante

No hay ninguna API para acceder al diccionario de propiedades de la aplicación en .NET MAUI.

Acceso a datos de propiedades de aplicaciones heredadas

El código siguiente muestra la clase LegacyApplication, que proporciona acceso a los datos de propiedades de la aplicación creados por la aplicación de Xamarin.Forms:

Nota:

Para usar este código, agrégalo a una clase denominada LegacyApplication en el proyecto de aplicación de .NET MAUI.

namespace MigrationHelpers;

public class LegacyApplication
{
    readonly PropertiesDeserializer deserializer;
    Task<IDictionary<string, object>>? propertiesTask;

    static LegacyApplication? current;
    public static LegacyApplication? Current
    {
        get
        {
            current ??= (LegacyApplication)Activator.CreateInstance(typeof(LegacyApplication));
            return current;
        }
    }

    public LegacyApplication()
    {
        deserializer = new PropertiesDeserializer();
    }

    public IDictionary<string, object> Properties
    {
        get
        {
            propertiesTask ??= GetPropertiesAsync();
            return propertiesTask.Result;
        }
    }

    async Task<IDictionary<string, object>> GetPropertiesAsync()
    {
        IDictionary<string, object> properties = await deserializer.DeserializePropertiesAsync().ConfigureAwait(false);
        properties ??= new Dictionary<string, object>(4);
        return properties;
    }
}

Android

En Android, la clase LegacyApplication usa la clase PropertiesDeserializer para deserializar datos del archivo de diccionario de propiedades de la aplicación. En el código siguiente se muestra la clase PropertiesDeserializer :

Nota:

Para usar este código, agrégalo a una clase denominada PropertiesDeserializer en la carpeta Platforms\Android del proyecto de aplicación de .NET MAUI.

using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization;
using System.Xml;

namespace MigrationHelpers;

public class PropertiesDeserializer
{
    const string PropertyStoreFile = "PropertyStore.forms";

    public Task<IDictionary<string, object>> DeserializePropertiesAsync()
    {
        // Deserialize property dictionary to local storage
        return Task.Run(() =>
        {
            using (IsolatedStorageFile store = IsolatedStorageFile.GetUserStoreForApplication())
            {
                if (!store.FileExists(PropertyStoreFile))
                    return null;

                using (IsolatedStorageFileStream stream = store.OpenFile(PropertyStoreFile, FileMode.Open, FileAccess.Read))
                using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
                {
                    if (stream.Length == 0)
                        return null;

                    try
                    {
                        var dcs = new DataContractSerializer(typeof(Dictionary<string, object>));
                        return (IDictionary<string, object>)dcs.ReadObject(reader);
                    }
                    catch (Exception e)
                    {
                        Debug.WriteLine("Could not deserialize properties: " + e.Message);
                        Console.WriteLine($"PropertyStore Exception while reading Application properties: {e}");
                    }
                }
            }
            return null;
        });
    }
}

iOS

En iOS, la clase LegacyApplication usa la clase PropertiesDeserializer para deserializar datos del archivo de diccionario de propiedades de la aplicación. En el código siguiente se muestra la clase PropertiesDeserializer :

Nota:

Para usar este código, agrégalo a una clase denominada PropertiesDeserializer en la carpeta Platforms\iOS del proyecto de aplicación de .NET MAUI.

using System.Diagnostics;
using System.IO.IsolatedStorage;
using System.Runtime.Serialization;
using System.Xml;

namespace MigrationHelpers;

public class PropertiesDeserializer
{
    const string PropertyStoreFile = "PropertyStore.forms";

    public Task<IDictionary<string, object>> DeserializePropertiesAsync()
    {
        // Deserialize property dictionary to local storage
        return Task.Run(() =>
        {
            using (var store = IsolatedStorageFile.GetUserStoreForApplication())
            using (var stream = store.OpenFile(PropertyStoreFile, System.IO.FileMode.OpenOrCreate))
            using (var reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
            {
                if (stream.Length == 0)
                    return null;

                try
                {
                    var dcs = new DataContractSerializer(typeof(Dictionary<string, object>));
                    return (IDictionary<string, object>)dcs.ReadObject(reader);
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Could not deserialize properties: " + e.Message);
                    Console.WriteLine($"PropertyStore Exception while reading Application properties: {e}");
                }
            }
            return null;
        });
    }
}

Windows

En Windows, la clase LegacyApplication usa la clase PropertiesDeserializer para deserializar datos del archivo de diccionario de propiedades de la aplicación. En el código siguiente se muestra la clase PropertiesDeserializer :

Nota:

Para usar este código, agrégalo a una clase denominada PropertiesDeserializer en la carpeta Platforms\Windows del proyecto de aplicación de .NET MAUI.

using System.Diagnostics;
using System.Runtime.Serialization;
using Windows.Storage;

namespace MigrationHelpers;

public class PropertiesDeserializer
{
    const string PropertyStoreFile = "PropertyStore.forms";

    public async Task<IDictionary<string, object>> DeserializePropertiesAsync()
    {
        try
        {
            StorageFile file = await ApplicationData.Current.RoamingFolder.GetFileAsync(PropertyStoreFile).DontSync();
            using (Stream stream = (await file.OpenReadAsync().DontSync()).AsStreamForRead())
            {
                if (stream.Length == 0)
                    return new Dictionary<string, object>(4);

                try
                {
                    var serializer = new DataContractSerializer(typeof(IDictionary<string, object>));
                    return (IDictionary<string, object>)serializer.ReadObject(stream);
                }
                catch (Exception e)
                {
                    Debug.WriteLine("Could not deserialize properties: " + e.Message);
                    Console.WriteLine($"PropertyStore Exception while reading Application properties: {e}");
                }
                return null;
            }
        }
        catch (FileNotFoundException)
        {
            return new Dictionary<string, object>(4);
        }
    }
}

Esta versión de Windows de la clase PropertiesDeserializer requiere el método de extensión DontSync. El siguiente código muestra este método de extensión:

Nota:

Para usar este código, agrégalo a una clase denominada Extensions en la carpeta Platforms\Windows del proyecto de aplicación de .NET MAUI.

using System.Runtime.CompilerServices;
using Windows.Foundation;

namespace MigrationHelpers;

internal static class Extensions
{
    public static ConfiguredTaskAwaitable<T> DontSync<T>(this IAsyncOperation<T> self)
    {
        return self.AsTask().ConfigureAwait(false);
    }
}

Consumo de datos de propiedades de aplicación heredada

La clase LegacyApplication se puede usar para consumir datos del diccionario de propiedades de la aplicación, en Android, iOS y Windows, que se creó con una versión anterior de Xamarin.Forms de la aplicación:

#if ANDROID || IOS || WINDOWS
using MigrationHelpers;
...

int id;
if (LegacyApplication.Current.Properties.ContainsKey("id"))
{
    id = (int)LegacyApplication.Current.Properties["id"];
    Preferences.Set("id", id);
}
#endif

En este ejemplo se muestra el uso de la clase LegacyApplication para leer un valor del diccionario de propiedades de la aplicación y, después, escribir el valor en preferencias de .NET MAUI.

Importante

Para evitar errores inesperados, comprueba que la clave esté en el diccionario de propiedades de la aplicación, antes de acceder.