;

Xamarin to MAUI Migration

Tips and tricks for migrating your Xamarin application to .NET MAUI

Xamarin to MAUI Migration

By Piyush Bhatt  at Jan 08, 2024  1 Comments

Should You Migrate

Xamarin will be going out of support on May 1, 2024. If you plan on actively updating your app after that date, you will need to migrate to MAUI. There are some other benefits, such as improved performance and app size (as long as you also migrate away from the deprecated features - StackLayout, RelativeLayout, Custom Renderers - instead of using the compatibility packages), a cleaner solution structure, and native desktop support.

The Easy Stuff

At a minimum, .NET 6 is required. It is recommended to upgrade to .NET 7 if possible. Familiarize yourself with the sorts of changes that will be necessary when going from Xamarin.Forms to MAUI - https://learn.microsoft.com/en-us/dotnet/maui/migration/multi-project-to-multi-project?view=net-maui-7.0 Then let the .NET Upgrade Assistant perform many of these changes for you - https://learn.microsoft.com/en-us/dotnet/maui/migration/upgrade-assistant?tabs=vswin

You can ensure that you have MAUI installed by launching PowerShell and running dotnet workload install maui

Manual Changes

There are significant differences in project structure and .csproj structure. I highly recommend creating a new MAUI project using the Visual Studio new project template and comparing the output of the .NET Upgrade Assistant to the new project incase something is not working as expected. The Upgrade Assistant may also not put everything in the same project, I recommend using the structure of the new project and moving files accordingly.

Bootstrapping

MAUI introduces a new platform independent startup class MauiProgram as the entry point for your application. If you're familiar with .NET, it looks similar to Startup where you have an app builder, can add services to the DI container, and do other startup configuration. Packages made for MAUI tend to have their setup take place in MauiProgram rather than in the platform specific startup classes MainApplication, MainActivity (Android), AppDelegate (iOS), however there still is some configuration that needs to happen in these classes, such as dealing with push notifications.

MainActivity and AppDelegate are also quite different than they were in Xamarin, I suggest referring to a new project created using the MAUI project template. The API changes are also documented in this section of the migration guide - https://learn.microsoft.com/en-us/dotnet/maui/migration/multi-project-to-multi-project?view=net-maui-7.0#bootstrap-your-migrated-app .

Layout

RelativeLayout is removed and should be replaced with a Grid or some other layout. You can add the xmlns for the compatibility namespace to continue using RelativeLayout, but this is not recommended.

StackLayout and the corresponding ...AndExpand VerticalOptions/HorizontalOptions are deprecated. They're still usable, but outside of a StackLayout ...AndExpand will function as though the AndExpand is not there, such as FillAndExpand acting just like Fill. These were deprecated for performance reasons, and its better to replace them with equivalent layouts, such as organizing with a Grid or using one of the two simpler layouts that were added to replace StackLayout, HorizontalStackLayout and VerticalStackLayout. These largely behave like StackLayout with Orientation=Horiztonal or Orientation=Vertical respectively, but also have some other differences to StackLayout.

Even if your app does not use RelativeLayout or StackLayout, your app will likely look slightly different than it used to in a lot of ways. Margins and paddings will be different, sizes of elements and text will be different, and many other things. Some of these can be fixed by defining your application defaults in the same way they were defined in Xamarin.Forms as defined here https://learn.microsoft.com/en-us/dotnet/maui/migration/layouts#default-layout-value-changes-from-xamarinforms . Likely you will need to make a lot of manual changes throughout your app to make it look like it used to.

Custom Renderers

There's two options you have for porting your custom renderers over to MAUI:

If your renderer is derived from FrameRenderer, ListViewRenderer, ShellRenderer, TableViewRenderer, or VisualElementRenderer, you can derive your renderer from the one of the classes provided by Microsoft.Maui.Controls.Compatibility library. This is a quick way to get your application compiling again, as the changes are relatively minimal. The full process is detailed here - https://learn.microsoft.com/en-us/dotnet/maui/migration/custom-renderers

The recommended long-term solution is to migrate all of your custom renderers to handlers. that process is detailed here - https://learn.microsoft.com/en-us/dotnet/maui/migration/renderer-to-handler

Xamarin Essentials

Many of the tools provided by the Xamarin.Essentials package have been built into MAUI Essentials that are automatically included in your project with <UseMaui>true</UseMaui> in your .csproj file. If you're looking for a feature from Xamarin.Essentials in MAUI, try the API Browser - https://learn.microsoft.com/en-us/dotnet/api/?view=net-maui-7.0

Some of these tools require extra steps to migrate for existing applications: SecureStorage and Preferences. If you want users SecureStorage and Preferences to carry over when updating from the Xamarin app to the MAUI app, follow the steps in these Microsoft tutorials: https://learn.microsoft.com/en-us/dotnet/maui/migration/secure-storage https://learn.microsoft.com/en-us/dotnet/maui/migration/app-properties If you do not need to carry over the SecureStorage and Preferences from the Xamarin version of the app, you'll likely only need to replace the namespace that you're importing.

Similar to MAUI Essentials, Xamarin Community Toolkit is now CommunityToolkit.MAUI and many of the same features are provided.

Packages

One of the most challenging parts of the upgrade process is making all of the libraries used by your Xamarin app work in MAUI. This becomes more complex when upgrading package versions and .NET version at the same time. This process is going to look different for every app and its unique dependencies - some will not work after upgrading and you'll either need to find a replacement or fix the source yourself. I'm going to go through the upgrade process for a few popular libraries that may be useful. As these packages and the tooling are constantly changing, some or all of the issues we encountered may be fixed.

Firebase

The official Microsoft packages for Firebase are the same as the Xamarin packages. In general, your project will probably still have a bunch of package references that start with Xamarin even after migrating to MAUI. Another option is to use the Plugin.Firebase - https://github.com/TobiasBuchholz/Plugin.Firebase - packages that were developed for MAUI specifically. Using this package instead of continuing to use the Xamarin packages will require more code changes, but the setup is pretty well documented - https://github.com/TobiasBuchholz/Plugin.Firebase/tree/development/docs .

When using either of these packages, we ran into two issues that were preventing the project from building:

Type androidx.lifecycle.DispatchQueue is defined multiple times

This can be fixed by adding the following package references to your .csproj:

<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'">
    <PackageReference Include="Xamarin.AndroidX.Activity" Version="1.7.2.2" />
    <PackageReference Include="Xamarin.AndroidX.Activity.Ktx" Version="1.7.2.2" />
<PackageReference Include="Xamarin.Kotlin.StdLib.Jdk7" Version="1.9.10.1" ExcludeAssets="build;buildTransitive" />
<PackageReference Include="Xamarin.Kotlin.StdLib.Jdk8" Version="1.9.10.1" ExcludeAssets="build;buildTransitive" />
</ItemGroup>
Could not find a part of the path

Some paths are too long for Windows to understand in the MAUI build tooling. In our case, the Xamarin.Firebase.iOS.CloudMessaging package fails to build due to this. We had to do two things: enable long paths support via registry, and move the NuGet package base path to C:\nuget:

1- Close all visual studio instances.  
2- Run PowerShell as Administrator and exeute this command.
New-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem" -Name "LongPathsEnabled" -Value 1 -PropertyType DWORD -Force
3- Create a new folder and name it "nuget" in C drive.
4- Again run PowerShell as Administrator and exeute this command

[Environment]::SetEnvironmentVariable("NUGET_PACKAGES", "C:\nuget" ,"Machine")

Twilio Video

Twilio currently does not have an official library for MAUI, but there are a few options. If you're willing to redo your video implementation in the "MAUI way", there's a package by Paul Varache that's worth keeping an eye on but is still in development - https://github.com/the49ltd/The49.Twilio.Video . If you want to just reuse your custom renderers from Xamarin, you can use just the binding projects from this repo directly The49.Twilio.Video.iOS and The49.Twilio.Video.Android and you'll only have to change some references and possibly make some code changes to match the Twilio Video API changes if you're upgrading from a lower version - for us, we had to change instances of .AddRenderer() to .AddSink() among other things. If you go this route, you might run into a Visual Studio bug with binding projects where it doesn't recognize namespaces from your binding projects when you reference the project directly. This can be fixed by referencing the built .dll from the binding project instead of the project itself.

Previous Post
Not available for the Jan, 2024
Next Post
Not available for the Jan, 2024

Join The Discussion

2 Comments

David Downs

test blog comment auto approve

August 30, 2024 at 2:39 PM Reply

Leave a Reply