Mit dem nahenden Ende des Supports für Xamarin im Mai 2024 sind Entwickler damit beschäftigt, bestehende Xamarin.Forms-Projekte auf .NET MAUI als Nachfolger zu migrieren. Das tun wir natürlich auch. In diesem Artikel zeige ich 7 Schritte, die wir während des Übergangs immer machen mussten, um Ihnen den Umstieg auf .NET MAUI zu erleichtern.
Mit .NET MAUI modernisiert Microsoft Xamarin Forms zu einem besseren plattformübergreifenden UI-Framework, das nicht nur architektonische und Implementierungsänderungen mit sich bringt, sondern auch den Wechsel zu anderen Zielplattformen wie Android, iOS, Mac OS (mit Mac Catalyst) und Windows ermöglicht. Volle Unterstützung für Samsungs Tizen wird ebenfalls geboten.
Sind Xamarin und Xamarin Forms vom Aussterben bedroht? Wenn Sie Xamarin nur als einen Produktnamen betrachten, dann ja. Xamarin als Framework wird als Teil von .NET MAUI und .NET für Android/ iOS unter neuen Namen weiterleben.
Die kurze Antwort ist nein. Die lange Antwort lautet, dass das MAUI-Team vieles von dem, was Xamarin-Entwickler an dem Framework kennen und lieben, in .NET MAUI und .NET für Android/ iOS integriert hat. Der Kompatibilitätsmodus in .NET MAUI ermöglicht es Ihnen, die meisten Ihrer benutzerdefinierten Xamarin Forms-Renderer und XAML-Layouts weiterhin zu verwenden. Eine Migration ist jedoch unvermeidlich, da sich viele kleine Dinge wie Namespaces zusammen mit der Projektstruktur geändert haben.
Mit den folgenden 7 Schritten konnten wir unsere .NET MAUI-Projekte erfolgreich von Xamarin.Forms wegmigrieren:
Sie haben ein Xamarin-Migrationsprojekt? Wir können Ihnen Zeit sparen.
Bevor Sie die Migration zu .NET MAUI selbst in die Hand nehmen, sprechen Sie mit uns. Unser Team aus erfahrenen Xamarin-Entwicklern freut sich darauf, Ihr Projekt zu besprechen und Ihnen bei der Konvertierung zu .NET MAUI zu helfen.
Jetzt einen Termin vereinbaren
Bevor Sie beginnen, sollten Sie einige Voraussetzungen erfüllen:
Microsoft hat die Struktur der Projekt- und Lösungsdatei mit .NET Core geändert und setzt diese fort. Diese Änderung wurde für Xamarin-Projekte noch nicht übernommen und wird nun mit .NET für Android und .NET für iOS sowie für .NET MAUI nachgeholt. Um Ihre Projektdatei zu ändern, öffnen Sie die csproj-Datei des Xamarin.Forms-Projekts und passen Sie sie entsprechend dem folgenden Beispiel an. Zum besseren Verständnis habe ich die wichtigsten Einträge mit Kommentaren versehen.
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<!-- Specify which platforms should be supported in your app -->
<TargetFrameworks>net7.0-ios;net7.0-android</TargetFrameworks>
<!-- Distinguishes .NET for Android or iOS from a MAUI project -->
<UseMaui>True</UseMaui>
<OutputType>Library</OutputType>
<ImplicitUsings>enable</ImplicitUsings>
<!-- Specify which version of a platform should be supported in your app -->
<SupportedOSPlatformVersion Condition="'$(TargetFramework)' == 'net7.0-ios'">15.4</SupportedOSPlatformVersion>
<SupportedOSPlatformVersion Condition="'$(TargetFramework)' == 'net7.0-android'">31.0</SupportedOSPlatformVersion>
<!-- Required for C# Hot Reload -->
<UseInterpreter Condition="'$(Configuration)' == 'Debug'">True</UseInterpreter>
</PropertyGroup>
<ItemGroup>
<MauiFont Include="Resources\*" />
</ItemGroup>
<ItemGroup>
<!-- If you used CommunityToolkit -->
<PackageReference Include="CommunityToolkit.Maui" Version="1.3.0" />
<!-- Add NuGet-references of your old project file here -->
</ItemGroup>
</Project>
Wenn Sie zu Beginn der Migration nicht komplett auf die neue „Einzelprojekt“-Struktur umsteigen wollen, können Sie die bestehenden Android- und iOS-Projekte beibehalten. Allerdings müssen diese Projekte dann auch auf den SDK-Stil umgestellt werden. Die Struktur ist die gleiche wie oben mit einer kleinen Anpassung - der OutputType-Wert ändert sich dann von Library zu Exe.
Wie zuvor beschrieben, müssen die NuGet-Referenzen hinzugefügt werden. Die Verweise auf Xamarin.Forms und Xamarin.Essentials werden nicht mehr benötigt.
Da nun alle Paketreferenzen in einer Projektdatei zusammengefasst sind, muss es eine Möglichkeit geben, sie je nach Plattform zu unterscheiden. Dazu fügen Sie der ItemGroup einfach eine Bedingung für jede Plattform hinzu. Am Beispiel des Google PlayService für Android sieht dies wie folgt aus:
<ItemGroup Condition="'$(TargetFramework)' == 'net7.0-android'">
<PackageReference Include="Xamarin.GooglePlayServices.Maps" Version="118.0.2" />
</ItemGroup>
Meiner Erfahrung nach reicht es in der Regel aus, für verwendete NuGet-Pakete auf neuere Versionen zu wechseln. Problematisch sind nur sehr alte Pakete, für die keine neuen Versionen mehr verfügbar sind. In diesem Fall hilft es meist, nach geeigneten Alternativen zu suchen oder, wenn es sich um ein Open-Source-Projekt handelt, die Änderung selbst vorzunehmen.
Ein Wort zu Xamarin.Essentials und Xamarin.CommunityToolkit. Während Xamarin.CommunityToolkit durch CommunityToolkit.Maui ersetzt wird, wird Xamarin.Essentials nicht mehr unterstützt. Das Ersetzen von Xamarin.CommunityToolkit ist ein wichtiger Schritt im Migrationsprozess, da er sicherstellt, dass die App weiterhin die Erweiterungen des Toolkits verwenden kann. Um das CommunityToolkit in MAUI zu verwenden, muss die Methode UseMauiCommunityToolkit im MauiApp-Builder hinzugefügt werden. Mehr dazu später im folgenden Abschnitt.
Während wir in Xamarin.Forms plattformspezifische Projekte hatten, wurde die App mit dem plattformspezifischen Code über die Methode Xamarin.Forms.Init gestartet. In .NET MAUI gibt es einen einzigen plattformübergreifenden App-Einstiegspunkt mit MauiProgram.cs. Über diesen statischen Einstiegspunkt wird auf jeder unterstützten Plattform eine MauiApp-Instanz erstellt und zurückgegeben. Wir müssen also eine neue Datei zum .NET MAUI-Projekt (oder dem alten Xamarin Forms-Projekt) hinzufügen und sie MauiProgram.cs nennen. .NET MAUI verwendet das bereits aus .NET Core bekannte Builder-Prinzip, was zu der untenstehenden Struktur von MauiProgram.cs führt:
public static class MauiProgram
{
public static MauiApp CreateMauiApp()
{
var builder = MauiApp.CreateBuilder();
builder
.UseMauiApp<App>()
.UseMauiCommunityToolkit()
.ConfigureFonts(fonts =>
{
fonts.AddFont("OpenSans-Regular.ttf", "OpenSansRegular");
});
return builder.Build();
}
}
Damit .NET MAUI auf Android funktioniert, müssen noch drei grundlegende Änderungen am alten Xamarin Android-Projekt vorgenommen werden.
OnRequestPermissionsResult
und löschen Sie den Aufruf der Methode LoadApplication
.Einige Änderungen müssen auch im iOS-Projekt vorgenommen werden.
Ihnen gefällt, wie wir die Dinge angehen?
Dieser Blog soll Ihnen einen kleinen Einblick in unseren Arbeitsalltag geben, wenn wir eine App in einer Full-Service-Umgebung entwickeln oder unsere Expertise als Expert-as-a-Service anbieten.
Mehr zur App-Entwicklung
.NET MAUI verwendet, wie Xamarin.Forms, ebenfalls XAML-Layouts. Sie können also Ihre bestehenden XAML-Layouts mit .NET MAUI weiterverwenden. Dazu müssen Sie die XML-Namespaces wie folgt ersetzen:
xmlns=„http://xamarin.com/schemas/2014/forms“
wird zu xmlns=„http://schemas.microsoft.com/dotnet/2021/maui“
.using Xamarin.Forms
wird entweder using Microsoft.Maui
oder using Microsoft.Maui.Controls
, je nach Anwendungsfall.Xamarin.Forms.Xaml
wird Microsoft.Maui.Controls.Xaml
.Aus Performance-Gründen wurde in MAUI das Horizontal- und VerticalStackLayout eingeführt. Es ersetzt das oft verwendete StackLayout. Sie sollten also auch hier Zeit investieren und Ihre Layouts dafür optimieren. Bitte werfen Sie einen Blick in die Microsoft-Dokumentation für weitere Informationen.
Es gibt auch andere Bereiche, in denen der Namensraum angepasst werden muss. Hier sind einige bekannte API-Änderungen, die Sie während der Migration sehen könnten:
Colors
wurde nach Microsoft.Maui.Graphics
verschoben.Shapes
wurde nach Microsoft.Maui.Controls
verschoben.BorderColor
für Frames existiert nicht in MAUIIcon
für ToolbarItems wird zu IconImageSource
.Image
für Buttons wird zu ImageSource
ForegroundColor
für Span existiert nicht in MAUISobald Sie mit den Schritten fertig sind, können Sie die Lösung in Visual Studio oder Visual Studio für Mac starten. Es ist sehr wahrscheinlich, dass weitere projektspezifische Fehler auftreten, z. B. durch API-Änderungen aufgrund neuerer NuGet-Paketversionen oder Namensraumänderungen, die Sie dann Schritt für Schritt beheben müssen.
Typischerweise gibt es Meldungen, die sich auf die AssemblyInfo.cs beziehen. Diese können Sie entfernen, da die meisten dieser Eigenschaften jetzt in der csproj sind. Wenn Sie mehr darüber erfahren möchten, wie Sie diese Eigenschaften einstellen, empfehle ich Ihnen, equivalent-to-assemblyinfo-in-dotnet-core-csproj auf Stackoverflow zu lesen.
Je nach Komplexität und Anzahl der Fehler ist es in manchen Fällen am einfachsten, ein neues MAUI-Projekt zu erstellen und dann Layouts, Dienste und NuGet-Referenzen hinzuzufügen. Dann, wenn Ihr Projekt startet, können Sie beginnen, Ihren Code Stück für Stück zu kopieren, um die Fehlerquelle besser zu lokalisieren.
Wir hier bei Cayas Software kennen kein Xamarin Forms-Projekt, in dem nicht mindestens ein Custom Renderer erstellt werden musste. Je nachdem, wie viele es in Ihrem Projekt gibt, lohnt es sich, diese gleich in die neue Handler-Struktur zu konvertieren. Wenn es doch zu viele sind, können Sie Ihre benutzerdefinierten Renderer weiter verwenden, indem Sie alles, was mit Xamarin.Forms.*
zu tun hat, auf Microsoft.Maui.*
aktualisieren und die ExportRenderer-Direktiven entfernen, da sie nicht mehr benötigt werden. Danach müssen Sie noch den Kompatibilitätsmodus in MauiProgram.cs über den Builder mit UseMauiCompatibility()
aktivieren.
// shortened
var builder = MauiApp.CreateBuilder();
.UseMauiCompatibility()
.ConfigureMauiHandlers((handlers) =>
{
handlers.AddCompatibilityRenderer(typeof("Your view"),typeof("Your renderer"));
});
Ich würde jedoch empfehlen, den benutzerdefinierten Handler zu verwenden, da er eine bessere Leistung und Erweiterbarkeit bietet. In unserem Artikel Erstellen eines .NET MAUI-Maps-Steuerelements zeigen wir, wie Sie einen benutzerdefinierten Handler erstellen können.
In .NET MAUI ist es jetzt viel einfacher, Dependency Injection durchzuführen. MAUI verfügt bereits über einen Container, in dem Sie Ihre Dienste registrieren und sie direkt in Ihre Klasse laden können, z. B. mit Hilfe von Contructor Injection. Sie brauchen also den DependecyService nicht mehr. Registrieren Sie einfach Ihren Dienst in der MauiProgram.cs wie unten gezeigt und entfernen Sie das Attribut [assembly: Dependency())]
aus Ihrer Dienstklasse.
// shortened
var builder = MauiApp.CreateBuilder();
builder.Services.AddSingleton(typeof(BluetoothService));
Um Ihren Dienst in Ihre Klasse zu bekommen, müssen Sie ihn nur über die Parameter übergeben und können ihn dann verwenden.
public partial class BluetoothSettingsPage : ContentPage
{
public BluetoothSettingsPage(BluetoothService bluetoothService)
{
InitializeComponent();
var isBluetoothOn = bluetoothService.IsBluetoothOn();
}
}
Ihnen gefällt, wie wir die Dinge angehen?
Sie haben es bis hierher geschafft, als Entwickler haben Sie einen Einblick in unsere Arbeit gewonnen. Migrationen sind nur ein Teil unserer Arbeit mit Xamarin und .NET MAUI. Wir unterstützen Sie in allen Bereichen der App-Entwicklung.
Lassen Sie uns reden
Um die neue .NET MAUI-Einzelprojektstruktur zu verwenden, müssen Sie die folgenden Schritte durchführen. Sie sind optional, bringen Ihr Projekt aber näher an die .NET MAUI-Projektstruktur heran.
Resources
zum Maui-Projekt hinzu, falls es noch keinen gibt, und kopieren Sie alle Bilder dorthin.Danach können Sie Ihre Projekte Forms.iOS und Forms.Android löschen.
Microsoft stellt mit dem .NET Upgrade Assistant ein Tool zur Verfügung, das viele der hier beschriebenen Schritte automatisch durchführt. Der Vorteil des .NET Upgrade Assistant ist, dass sowohl Projektdateien, NuGet-Pakete als auch Teile des Quellcodes aktualisiert werden. Zum Zeitpunkt der Erstellung dieses Artikels müssen jedoch noch viele Stellen manuell angepasst werden. Außerdem unterstützt der Upgrade Assistant nur C# und Visual Basic, wodurch F# (F-Sharp) auf der Strecke bleibt.
Um auszuprobieren, ob er in Ihrem Projekt besser funktioniert, sind zwei Schritte erforderlich:
dotnet tool update --global upgrade-assistant
.upgrade-assistant upgrade <Pfad zu sln oder csproj> --non-interactive --entry-point *
.Wie Sie sehen, ist die Migration einer Xamarin.Forms-App zu .NET MAUI in wenigen Schritten erledigt, wenn Sie die genannten Punkte beachten. Vielleicht wird der .NET Upgrade Assistant in naher Zukunft in der Lage sein, alles automatisiert zu migrieren und wir müssen nur noch sehr wenig manuelle Arbeit leisten. Bis dahin versucht dieser Leitfaden, Ihnen einen guten Start zu ermöglichen. Lassen Sie mich wissen, wie Ihre Migration verlaufen ist und wo es Probleme gab. Ich bin sicher, wir können Ihnen helfen. Sie finden den Quellcode in unserem öffentlichen Bitbucket Repository: MAUI-Migration.
Mit über 7 Jahren Erfahrung in der Entwicklung von Cross-Plattform-Apps mit Xamarin und .NET MAUI zählt Martin zu den alten Hasen bei Cayas Software. Kunden aus Agrar-, Logistik- oder der Gesundheitsbranche schätzen seine ruhige Art und das analytische Vorgehen bei der Umsetzung ihrer Xamarin und .NET MAUI-Projekte. Ein Teil aus seiner täglichen Arbeit mit Xamarin und .NET MAUI teilt er in seinen Artikeln.
Ich arbeite derzeit an der Portierung einer Xamarin Forms App zu .NET MAUI. Die App verwendet auch Karten von Apple oder Google Maps, um Standorte anzuzeigen. Obwohl es bis zur Veröffentlichung von .NET 7 keine offizielle Unterstützung in MAUI gab, möchte ich Ihnen eine Möglichkeit zeigen, Karten über einen benutzerdefinierten Handler anzuzeigen.
.NET MAUI ermöglicht es uns, plattform- und geräteunabhängige Anwendungen zu schreiben, was eine dynamische Anpassung an die Bildschirmgröße und -form des Benutzers erforderlich macht. In diesem Blog-Beitrag erfahren Sie, wie Sie Ihre XAML-Layouts an unterschiedliche Geräteausrichtungen anpassen können. Dabei verwenden Sie eine ähnliche Syntax wie OnIdiom und OnPlatform, die Ihnen vielleicht schon bekannt ist.
This post is a continuation of the Hackathon topic post, where the technical implementation of voice commands in .NET MAUI is revealed, as well as the challenges the development team faced and how they successfully solved them.