Поделиться через


Перенос данных из словаря свойств приложения Xamarin.Forms в настройки .NET MAUI

В Xamarin.Forms есть Properties словарь, который можно использовать для хранения данных и доступ к которому осуществляется с помощью Application.Current.Properties свойства. Словарь использует ключ string и хранит значение object. Значения в словаре сохраняются на устройстве при приостановке или завершении работы приложения, а также загружаются при перезапуске или возвращении приложения из фонового режима. Дополнительные сведения о словаре свойств см . в словаре свойств.

При переносе приложения Xamarin.Forms, которое хранит данные в словаре свойств приложения в .NET MAUI, эти данные следует перенести в параметры .NET MAUI. Это можно сделать с помощью LegacyApplication класса и вспомогательных классов, представленных в этой статье. Этот класс позволяет приложению .NET MAUI в Android, iOS и Windows считывать данные из словаря свойств приложения, созданного с предыдущей версией приложения Xamarin.Forms. Дополнительные сведения о параметрах .NET MAUI см. в разделе "Параметры".

Внимание

Нет API для доступа к словарю свойств приложения в .NET MAUI.

Доступ к данным свойств устаревшего приложения

В следующем коде LegacyApplication показан класс, который предоставляет доступ к данным свойств приложения, созданным приложением Xamarin.Forms:

Примечание.

Чтобы использовать этот код, добавьте его в класс с именем LegacyApplication в проекте приложения .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

В Android LegacyApplication класс использует PropertiesDeserializer класс для десериализации данных из файла словаря свойств приложения. В следующем коде демонстрируется класс PropertiesDeserializer:

Примечание.

Чтобы использовать этот код, добавьте его в класс с именем PropertiesDeserializer в папке Platform\Android проекта приложения .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

В iOS LegacyApplication класс использует PropertiesDeserializer класс для десериализации данных из файла словаря свойств приложения. В следующем коде демонстрируется класс PropertiesDeserializer:

Примечание.

Чтобы использовать этот код, добавьте его в класс с именем PropertiesDeserializer в папке Platform\iOS проекта приложения .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

В LegacyApplication Windows класс использует PropertiesDeserializer класс для десериализации данных из файла словаря свойств приложения. В следующем коде демонстрируется класс PropertiesDeserializer:

Примечание.

Чтобы использовать этот код, добавьте его в класс с именем PropertiesDeserializer в папке Platform\Windows проекта приложения .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);
        }
    }
}

Для этой версии PropertiesDeserializer класса Windows требуется DontSync метод расширения. В следующем коде показан этот метод расширения:

Примечание.

Чтобы использовать этот код, добавьте его в класс с именем Extensions в папке Platform\Windows проекта приложения .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);
    }
}

Использование устаревших данных свойств приложения

Класс LegacyApplication можно использовать для использования данных из словаря свойств приложения, в Android, iOS и Windows, созданной с предыдущей версией приложения Xamarin.Forms:

#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

В этом примере показано использование LegacyApplication класса для чтения значения из словаря свойств приложения, а затем записи значения в параметры .NET MAUI.

Внимание

Всегда проверка для наличия ключа в словаре свойств приложения перед доступом к нему, чтобы предотвратить непредвиденные ошибки.