Eseguire la migrazione dei dati dal dizionario delle proprietà dell'app Xamarin.Forms alle preferenze MAUI .NET

Xamarin.Forms include un Properties dizionario che può essere usato per archiviare i dati e a cui si accede tramite la Application.Current.Properties proprietà . Il dizionario usa una chiave string e archivia un valore object. I valori nel dizionario vengono salvati nel dispositivo quando un'app viene sospesa o arrestata e caricata quando un'app viene riavviata o viene restituita dallo sfondo. Per altre informazioni sul dizionario delle proprietà, vedere Dizionario proprietà.

Quando si esegue la migrazione di un'app Xamarin.Forms che archivia i dati nel dizionario delle proprietà dell'app a .NET MAUI, è consigliabile eseguire la migrazione di questi dati alle preferenze MAUI .NET. Questa operazione può essere eseguita con la LegacyApplication classe e le classi helper, presentate in questo articolo. Questa classe consente all'app .NET MAUI in Android, iOS e Windows di leggere i dati dal dizionario delle proprietà dell'app creato con una versione precedente di Xamarin.Forms dell'app. Per altre informazioni sulle preferenze MAUI .NET, vedere Preferenze.

Importante

Non esiste alcuna API per accedere al dizionario delle proprietà dell'app in .NET MAUI.

Accedere ai dati delle proprietà dell'app legacy

Il codice seguente illustra la LegacyApplication classe , che fornisce l'accesso ai dati delle proprietà dell'app creati dall'app Xamarin.Forms:

Nota

Per usare questo codice, aggiungerlo a una classe denominata LegacyApplication nel progetto di app MAUI .NET.

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

In Android la LegacyApplication classe usa la PropertiesDeserializer classe per deserializzare i dati dal file di dizionario delle proprietà dell'app. Il codice seguente illustra la PropertiesDeserializer classe :

Nota

Per usare questo codice, aggiungerlo a una classe denominata PropertiesDeserializer nella cartella Platforms\Android del progetto di app MAUI .NET.

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

In iOS la LegacyApplication classe usa la PropertiesDeserializer classe per deserializzare i dati dal file di dizionario delle proprietà dell'app. Il codice seguente illustra la PropertiesDeserializer classe :

Nota

Per usare questo codice, aggiungerlo a una classe denominata PropertiesDeserializer nella cartella Platforms\iOS del progetto di app MAUI .NET.

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

In Windows la LegacyApplication classe usa la PropertiesDeserializer classe per deserializzare i dati dal file di dizionario delle proprietà dell'app. Il codice seguente illustra la PropertiesDeserializer classe :

Nota

Per usare questo codice, aggiungerlo a una classe denominata PropertiesDeserializer nella cartella Platforms\Windows del progetto di app MAUI .NET.

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);
        }
    }
}

Questa versione di Windows della PropertiesDeserializer classe richiede il DontSync metodo di estensione. Il codice seguente illustra questo metodo di estensione:

Nota

Per usare questo codice, aggiungerlo a una classe denominata Extensions nella cartella Platforms\Windows del progetto di app MAUI .NET.

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);
    }
}

Utilizzare i dati delle proprietà dell'app legacy

La LegacyApplication classe può essere usata per utilizzare i dati dal dizionario delle proprietà dell'app, in Android, iOS e Windows, creato con una versione precedente di Xamarin.Forms dell'app:

#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

Questo esempio mostra l'uso della LegacyApplication classe per leggere un valore dal dizionario delle proprietà dell'app e quindi scrivere il valore nelle preferenze MAUI .NET.

Importante

Verificare sempre la presenza della chiave nel dizionario delle proprietà dell'app prima di accedervi, per evitare errori imprevisti.