Accessing Xamarin Forms App Properties in .NET MAUI

By | September 7, 2023

There were two primary ways to store preferences in Xamarin Forms. You could use either App
Properties or Xamarin Essentials Preferences. Both are similar, with key/value pairs that are stored somewhere that the application can access, but private to the application. You could remember a username, store application preferences like colors and other customizations, and similar types of data. Although these two implementations are similar in behavior, they store the data very differently.

If you were lucky enough to choose Xamarin Essentials Preferences for your Xamarin Forms app, things should just work in .NET MAUI, because the Preferences in MAUI are based on the Xamarin Essentials implementation.

However, if you chose the App Properties implementation in Xamarin Forms, there is no easy way to access these settings in MAUI.

One thing you could do is in your Xamarin Forms app you can add logic to migrate to Xamarin Essentials Preferences, and then as long as your users update the app once before you release a MAUI version, all should be fine. This is a big if though, it would be hard to guarantee that your users run the updated Xamarin Forms version at least once before you release a MAUI version.

All hope is not lost though, because the App Properties are simply stored in a file in application storage as a serialized object, and as long as we get the right location, we should be able to read the file and get the data in MAUI and migrate it.

I recently had to tackle this issue, so the first thing I did was look at the Xamarin Forms code and tried to migrate it directly to MAUI. This code uses the following logic to find the path to the file:

var store = IsolatedStorageFile.GetUserStoreForApplication()

And the file is always named PropertyStore.forms. Now we just need to read this file, right? Not exactly. Unfortunately, the GetUserStoreForApplication method call returns a different path in MAUI than it does in Xamarin Forms. So we need to construct the correct path for the file. Once we get access to the file it’s a simple process of deserializing it into a dictionary. In MAUI, we can do all of this in shared code, no platform specific code required. since the goal of this is to be able to read the properties and rewrite them into MAUI Preferences, I kept things as simple as possible without a bunch of access methods to get a specific value. Here is my implementation of a class that returns the dictionary.

using System.Diagnostics;
using System.Runtime.Serialization;
using System.Xml;

namespace XamarinFormsPreferences.MauiCompat;

public static class Preferences
{
    const string PropertyStoreFile = "PropertyStore.forms";
    static IDictionary<string, object> props;
    static bool initialized = false;

    public static IDictionary<string, object> GetProperties()
    {
        if (initialized) return props;
        IDictionary<string, object> properties = DeserializeProperties();
        if (properties == null)
            properties = new Dictionary<string, object>();
        props = properties;
        initialized = true;
        return properties;
    }

    private static IDictionary<string, object> DeserializeProperties()
    {
        string preferencesFile = $"{Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments)}/.config/.isolated-storage/{PropertyStoreFile}";
        try
        {
            if (File.Exists(preferencesFile))
            {
                using (FileStream stream = File.OpenRead(preferencesFile))
                {
                    using (XmlDictionaryReader reader = XmlDictionaryReader.CreateBinaryReader(stream, XmlDictionaryReaderQuotas.Max))
                    {
                        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);
                        }
                    }
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Error processing Xamarin App Properties file: " + ex.Message);
            return null;
        }
        return null;
    }
}

You will want your MAUI app to have the same bundle name as your Xamarin Forms app. On Android, you can verify that you can access your Xamarin Forms App Properties data if you run the Xamarin Forms version of your app, store some properties, and then run the MAUI version to verify that you can see the properties. On iOS, every time you build and deploy, the path to the application data changes, so it’s very hard to verify unless you publish the app.

One thought on “Accessing Xamarin Forms App Properties in .NET MAUI

  1. Pingback: Dew Drop – September 8, 2023 (#4021) – Morning Dew by Alvin Ashcraft

Leave a Reply

Your email address will not be published. Required fields are marked *