Migrar dados do dicionário de propriedades do aplicativo Xamarin.Forms para preferências do .NET MAUI
Xamarin.Forms possui um dicionário Properties
que pode ser usado para armazenar dados e que é acessado usando a propriedade Application.Current.Properties
. Esse dicionário usa uma chave string
e armazena um valor de object
. Os valores no dicionário são salvos no dispositivo quando um aplicativo é pausado ou desligado e carregados quando um aplicativo é reiniciado ou retorna do segundo plano. Para obter mais informações sobre o dicionário de propriedades, veja Dicionário de propriedades.
Ao migrar um aplicativo Xamarin.Forms que armazena dados no dicionário de propriedades do aplicativo para o .NET MAUI, você deve migrar esses dados para as preferências do .NET MAUI. Isso pode ser feito com a classe LegacyApplication
e classes auxiliares, apresentadas nesse artigo. Essa classe permite que seu aplicativo .NET MAUI no Android, iOS e Windows leia dados do dicionário de propriedades do aplicativo que foi criado com uma versão anterior do Xamarin.Forms do seu aplicativo. Para obter mais informações sobre as preferências do .NET MAUI, veja Preferências.
Importante
Não há API para acessar o dicionário de propriedades do aplicativo no .NET MAUI.
Acesse dados de propriedades de aplicativos herdados
O código a seguir mostra a classe LegacyApplication
, que fornece acesso aos dados de propriedades do aplicativo criados pelo seu aplicativo Xamarin.Forms:
Observação
Para usar esse código, adicione-o a uma classe chamada LegacyApplication
em seu projeto de aplicativo .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
No Android, a classe LegacyApplication
usa a classe PropertiesDeserializer
para desserializar dados do arquivo de dicionário de propriedades do aplicativo. O código a seguir mostra a classe PropertiesDeserializer
:
Observação
Para usar esse código, adicione-o a uma classe chamada PropertiesDeserializer
na pasta Platforms\Android do seu projeto de aplicativo .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
No iOS, a classe LegacyApplication
usa a classe PropertiesDeserializer
para desserializar dados do arquivo de dicionário de propriedades do aplicativo. O código a seguir mostra a classe PropertiesDeserializer
:
Observação
Para usar esse código, adicione-o a uma classe chamada PropertiesDeserializer
na pasta Platforms\iOS do seu projeto de aplicativo .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
No Windows, a classe LegacyApplication
usa a classe PropertiesDeserializer
para desserializar dados do arquivo de dicionário de propriedades do aplicativo. O código a seguir mostra a classe PropertiesDeserializer
:
Observação
Para usar esse código, adicione-o a uma classe chamada PropertiesDeserializer
na pasta Platforms\Windows do seu projeto de aplicativo .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);
}
}
}
Essa versão do Windows da classe PropertiesDeserializer
requer o método DontSync
extensão. O código a seguir mostra esse método de extensão:
Observação
Para usar esse código, adicione-o a uma classe chamada Extensions
na pasta Platforms\Windows do seu projeto de aplicativo .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);
}
}
Consumir dados de propriedades de aplicativos herdados
A classe LegacyApplication
pode ser usada para consumir dados do dicionário de propriedades do aplicativo, no Android, iOS e Windows, que foi criado com uma versão anterior do Xamarin.Forms do seu aplicativo:
#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
Esse exemplo mostra o uso da classe LegacyApplication
para ler um valor do dicionário de propriedades do aplicativo e, em seguida, gravar o valor nas preferências do .NET MAUI.
Importante
Sempre verifique a presença da chave no dicionário de propriedades do aplicativo antes de acessá-lo, para evitar erros inesperados.