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.