Xamarin.Forms アプリのプロパティ ディクショナリから .NET MAUI 基本設定にデータを移行する
Xamarin.Forms にはデータの格納に使用できる Properties
ディクショナリがあり、Application.Current.Properties
プロパティを使用してアクセスできます。 このディクショナリでは、string
キーが使用され、object
値が格納されます。 ディクショナリ内の値は、アプリが一時停止またはシャットダウンされるときにデバイスに格納され、アプリが再起動されるとき、またはバックグラウンドから戻るときに読み込まれます。 プロパティ ディクショナリの詳細については、「プロパティ ディクショナリ」をご覧ください。
アプリ プロパティ ディクショナリにデータを格納する Xamarin.Forms アプリを .NET MAUI に移行する場合は、このデータを .NET MAUI 基本設定に移行する必要があります。 これは、この記事で紹介する LegacyApplication
クラスとヘルパー クラスを使用して実現できます。 このクラスを使用すると、Android、iOS、Windows 上の .NET MAUI アプリで、以前の Xamarin.Forms バージョンのアプリで作成されたアプリ プロパティ ディクショナリからデータを読み取ることができます。 .NET MAUI の基本設定の詳細については、「基本設定」をご覧ください。
重要
.NET MAUI のアプリ プロパティ ディクショナリにアクセスするための API はありません。
従来のアプリのプロパティ データにアクセスする
次のコードは、Xamarin.Forms アプリで作成されたアプリ プロパティ データへのアクセスを提供する LegacyApplication
クラスを示しています。
Note
このコードを使用するには、.NET MAUI アプリ プロジェクトの LegacyApplication
という名前のクラスに追加します。
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
クラスを示しています。
Note
このコードを使用するには、.NET MAUI アプリ プロジェクトの Platforms\Android フォルダーにある PropertiesDeserializer
という名前のクラスにこのコードを追加します。
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
クラスを示しています。
Note
このコードを使用するには、.NET MAUI アプリ プロジェクトの Platforms\iOS フォルダーにある PropertiesDeserializer
という名前のクラスにこのコードを追加します。
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
Windows では、LegacyApplication
クラスは PropertiesDeserializer
クラスを使用して、アプリ プロパティ ディクショナリのファイルからデータを逆シリアル化します。 次のコードは PropertiesDeserializer
クラスを示しています。
Note
このコードを使用するには、.NET MAUI アプリ プロジェクトの Platforms\Windows フォルダーにある PropertiesDeserializer
という名前のクラスに追加します。
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);
}
}
}
この Windows バージョンの PropertiesDeserializer
クラスには、DontSync
拡張メソッドが必要です。 以下のコード例は、この拡張メソッドを示しています。
Note
このコードを使用するには、.NET MAUI アプリ プロジェクトの Platforms\Windows フォルダーにある Extensions
という名前のクラスに追加します。
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 基本設定に書き込む方法を示しています。
重要
予期しないエラーを回避するために、必ずアプリ プロパティ ディクショナリにキーが存在することを確認してからアクセスしてください。
.NET MAUI