Xamarin.Forms im Praxiseinsatz: Wie viel Code Sharing ist realistisch?

22. Mai 2015

Einer der Vorteile von Xamarin.Forms gegenüber Xamarin.iOS und Xamarin.Android ist die plattformübergreifende Verwendung von Views. Dadurch wird der jeweilige Mehraufwand pro zu unterstützende Plattform geringer. Dieser Artikel beschreibt, welchen Prozentsatz an Code Sharing wir in einem aktuellen Xamarin.Forms Kundenprojekt realisieren konnten und gibt zusätzlich Tipps zum Erreichen eines solchen Prozentsatzes.

 

Code-Strukturierung in einem Xamarin.Forms Projekt

Im Allgemeinen besteht eine Xamarin.Forms Solution aus jeweils einem Projekt pro zu unterstützende Plattform und einem (oder mehreren) plattformübergreifenden Projekten. Für die plattformübergreifenden Projekte gibt es zwei unterschiedliche Lösungsansätze:

  • Shared Projects
  • Portable Class Libraries (PCL)

Shared Projects liegt die Idee zu Grunde, den enthaltenen Code für die jeweilige Plattform zu kopieren und erneut zu übersetzen. Auf diese Weise wird keine neue Assembly erzeugt, sondern der Code direkt in die Assembly des referenzierenden Projekts integriert. So kann der Code dieser Assembly auf mehreren Plattformen wiederverwendet werden und zugleich über Präprozessordirektiven oder partielle Methoden und Klassen in den nativen Projekten auf plattformspezifische Anforderungen eingegangen werden, ohne zusätzliche Abstraktionsschichten für die nativen Funktionen einbauen zu müssen. Solch ein Projekt hat allerdings den Nachteil, dass aufgrund der fehlenden oder zu starken Codetrennung die Übersicht im Code und somit die Wartbarkeit schnell verloren geht.

PCLs hingegen bieten die Möglichkeit, mit gemeinsamer Funktionalität ausgewählter Zielplattformen gemeinsamen Code in einer Assembly abzubilden. Da in dem Kundenprojekt das innerhalb einer Xamarin-kompatiblen PCL verfügbare Subset des .NET Frameworks ausreichend war und die meisten benötigten nativen Features als Plugins vorhanden waren, wurde der PCL Ansatz gewählt. Um ein möglich effizientes Code Sharing mit einer nativen Windows 8 App zu erreichen, wurde der plattformübergreifende Code auf zwei Projekte aufgeteilt. Diese Trennung hat es ermöglicht, Business-Logik und ViewModels mit einem alternativen UI Framework (in diesem Fall WinRT) wiederzuverwenden.

architektur

Die einzelnen Projekte beinhalten:

  • Portable-Projekt (PCL):
    • Business-Logik
    • ViewModels
  • Forms-Projekt (PCL):
    • Views
    • Converter
    • Plattformunabhängige Custom Controls
  • Forms.iOS (nativ) und Forms.Android (nativ) Projekt:
    • Plattformspezifische Startdatei (iOS: AppDelegate.cs, Android: MainActivity.cs)
    • Plattformspezifische Custom Control Renderer
    • Plattformspezifische Services

 

Code Sharing

Der folgende Screenshot zeigt die Aufteilung der Lines of Code auf die einzelnen Projekte:

lines of code

Für die iOS App ergibt sich damit ein plattformabhängiger Anteil von 13% (Forms.iOS / (Portable + Forms + Forms.iOS)). Für die Android App ergibt sich ein plattformabhängiger Anteil von 6% (Forms.Android / (Portable + Forms + Forms.Android)). Hierbei ist aber zu beachten, dass es sich bei den 13% bzw. 6% nicht um komplett selbst geschriebenen Code handelt, sondern vor allem um die Implementierung der benötigten Device Features (in dem Kundenprojekt zum Beispiel der Dateizugriff). Hierzu gibt es mehrere passende Quellen für alle gängigen Device Features:

Der tatsächlich plattformspezifische, selbst geschriebene Code war vor allem die Implementierung von  Custom Control Renderer, um die von Xamarin.Forms vorgegebene Visualisierung von UI Controls zu modifizieren. Ein Beispiel hierfür ist ein zusätzlich unter iOS notwendiger Disclosure Indicator für Listenelemente.

Fazit

Durch den Einsatz von Xamarin.Forms und einer durchdachten Code-Struktur ist es möglich, den plattformabhängigen Code auf ein Minimum zu reduzieren und dennoch native Oberflächen zu implementieren.