en
de

Native mobile Apps für iOS und Android mit Xamarin

27 Mai 2013
| |
Lesezeit: 5 Minutes

Ausgangslage

Eine Vielzahl der aktuellen Webservices ist gemäss dem REST-Paradigma aufgebaut. Dies ermöglicht im Zusammenhang mit entsprechender Hardware (z. B. Cloud) eine einfache Skalierbarkeit, stellt gleichzeitig aber auch die plattformunabhängige Konsumation seitens der Clients sicher. In meinem Szenario bildet ein solcher Service die Grundlage für mobile Anwendungen. Trotz dem Vormarsch von HTML5 fällt dabei der Entscheid oft und bewusst zugunsten nativer Apps. Als erfahrener und begeisterter .NET-Entwickler (in C#) hält Xamarin für mich die perfekten Werkzeuge bereit, um eine solche Anforderung schnell und effizient zu erfüllen.

Ich bin mir bewusst, dass „nativ“ im Zusammenhang mit Cross-Compiling nicht ganz korrekt ist. Im Kontext dieses Artikels beziehe ich mich mit dem Term „nativ“ darauf, dass die resultierenden Apps in den jeweiligen Stores publiziert und auf den Smartphones über die offiziellen Kanäle installiert werden können.

Serverzugriff

Mit Hilfe von ServiceStack lassen sich REST-Services komfortabel und schnell aus .NET benutzen. Entwickelt man in Visual Studio, so fügt man die benötigten Bibliotheken am einfachsten per NuGet hinzu. In unserem Fall brauchen wir jedoch die Versionen für MonoTouch (iOS) respektive MonoDroid (Android). Damit bauen wir den gemeinsamen Business-Layer für den Serverzugriff, den wir 1:1 sowohl für iOS als auch Android verwenden.

Schema Xamarin

Schematische Darstellung der Xamarin-Lösung

Unser Service liefert die Daten im JSON-Format, welches gerade für mobile Clients (langsame Verbindungen, beschränktes Datenvolumen) den Vorteil mit sich bringt, dass es kompakt ist und wenig Ballast enthält.

[{"Id":1,"Title":"Mrs","FirstName":"Lilliane","MiddleName":"Catrina","LastName":"Wyss","Company":"Volkswagen","WebPage":"http://www.volkswagen.com","PhoneNumber":"+65 (1418) 832671","FaxNumber":"+21 (4004) 257244","MobileNumber":"+91 (6007) 144197","Street":"Lake Street 343","Email":"nadia.huber@volkswagen.com","City":"Madison","State":"","PostalCode":"42481","Country":"Western Sahara","Department":"NPP","Office":"225","Profession":"welder","ManagersName":"Leopoldo Keller","AssistantName":"Agnes Weber","Nickname":"The Unpredictable","Birthday":"/Date(1042844400000+0100)/"}]

Als Entwickler kümmern uns die Formatdetails wenig, da uns ServiceStack das Parsen in beide Richtungen vollständig abnimmt. Zuerst instantiieren wir den Client mit der Basis-URL unseres Services:

var restClient = new JsonServiceClient("http://yoursubdomain.azurewebsites.net");

Anschliessend können darauf beliebige HTTP-Requests abgesetzt werden. Beispielsweise ein GET, um die Liste aller Kunden zu laden:

var customers = restClient.Get<List<Customer>>("/customer");

Die Klasse Customer enthält sämtliche Properties, welche man von ServiceStack automatisch deserialisieren lassen möchte. Wobei der Name des Propertys dem JSON-Feldnamen entsprechen muss. Da wir unseren Service im Vorfeld ebenfalls mit C# geschrieben und publiziert hatten, können wir direkt die dort verwendete Customer-Klasse in unser Mono-Projekt kopieren. Auszugsweise sieht die Klasse wie folgt aus:

public class Customer : IHasResponseStatus
{
   public int Id { get; set; }
   public string FirstName { get; set; }
   public string LastName { get; set; }
   public ResponseStatus ResponseStatus { get; set; }

   public override string ToString()
   {
      return string.Format("{0} {1} ({2})", FirstName, LastName, Id);
   }
}

Zusätzlich zu der erwähnten Methode, um eine Liste aller Kunden zu erhalten, enthält der CustomerProvider weitere Methoden, um Kundendetails abzurufen oder einzelne Kunden zu manipulieren.

public interface ICustomerProvider
{
   List<Customer> GetCustomers();
   Customer GetCustomer(int customerId);
   Customer CreateOrUpdateCustomer(Customer customer);
   Customer DeleteCustomer(Customer customer);
}

Eine statische Factory-Klasse, um sich einen CustomerProvider generieren zu lassen, rundet das Serverzugriff-Projekt ab und kann von den beiden folgenden Clients verwendet werden. Meine Erfahrungen diesbezüglich haben gezeigt, dass das Code-Sharing mit separater Kompilierung pro Plattform einfach und stabil ist, während das Einbinden eines zuvor kompilierten, allgemeinen Assemblys in die beiden Plattform-Projekte sehr oft zu Problemen führt.

iOS

Die erste Ansicht soll sämtliche Kunden selektierbar anzeigen. Dazu wird die in iOS allgegenwärtige TableView verwendet. In Xamarin erstellen wir dafür eine eigene TableViewSource, indem wir von der Klasse UITableViewSource ableiten und mindestens die beiden Methoden

  • int NumberOfSections (UITableView tableView);
  • UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath);

überschreiben. In der Methode GetCell verwenden wir den bestehenden Zellenstil UITableViewCellStyle.Default (einfacher Text) mit dem Accessory UITableViewCellAccessory.DisclosureIndicator (Detail-Pfeil auf der rechten Seite). Weitere Features wie Kopfzeilen, Fusszeilen oder alphabetischer Schnellindex lassen sich durch Überschreiben weiterer Methoden hinzufügen. Auch das Verhalten bei Selektion lässt sich durch Überschreiben der Methode

  • void RowSelected (UITableView tableView, NSIndexPath indexPath);

bestimmen. In diesem Fall instantiieren und laden wir einen neuen ViewController mit den Detaildaten des gewählten Kunden. Dafür verwenden wir die in Xamarin mitgelieferte Bibliothek MonoTouch.Dialog. Damit lassen sich sehr einfach ansprechende Views erstellen, wie wir sie beispielsweise aus den Einstellungen von iOS kennen. Das UI wird automatisch aufgrund der Daten aufgebaut. Wir können dafür die bereits bekannte Customer-Klasse verwenden, die wir kopieren und mit einem Copy-Konstruktor sowie den gewünschten Attributen zur Beeinflussung der Darstellungsart anreichern.

iOS List

Kundenliste in iOS

iOS Details

Kundendetails mit MonoTouch.Dialog

Mit einer zusätzlichen Kopie der Customer-Klasse und MonoTouch.Dialog lässt sich analog auch die View zum Erstellen/Verändern eines Kunden erstellen.

Android

Im Android-Projekt ist das Vorgehen analog zu iOS: Der Serverzugriff erfolgt über das gemeinsame Projekt und die Kundenliste wird auf einer ersten View mittels ListView (Pendant zur iOS-TableView) dargestellt. Dazu muss ein sogenannter Adapter geschrieben werden, welcher die Daten für die ListView aufbereitet. Die eigene Adapter-Klasse leitet von BaseAdapter ab und implementiert mindestens die folgenden Methoden:

  • int Count [Property]
  • Java.Lang.Object GetItem(int position); [darf NotSupportedException werfen, wird nicht aufgerufen]
  • long GetItemId(int position);
  • View GetView(int position, View convertView, ViewGroup parent);

Das Aussehen einer Zelle definieren wir in einer einfachen XML-Ressource und laden sie mit der Inflate-Methode des LayoutInflater.

Um auf die Selektion eines Kunden reagieren zu können, melden wir uns auf den ItemClick-Event der ListView an und laden in diesem Fall die Detailansicht. Diese müssen wir – im Gegensatz zu iOS mit MonoTouch.Dialog – im Designer (oder von Hand mittels XML) erstellen. Um die gleiche View sowohl für Ansicht als auch Bearbeitung des Kunden verwenden zu können, bietet es sich an, die Datenfelder in beiden Fällen als EditText-Felder zu definieren und im Ansichtmodus deren Enabled-Properties auf false zu setzen.

Android-List

Kundenliste in Android

Android-Details

Kundendetails in Android

Im Bearbeitungsmodus aktivieren wir sämtliche EditText-Felder der Detailansicht.

Fazit

Die Werkzeuge von Xamarin befähigen einen erfahrenen C#-Entwickler in sehr kurzer Zeit, „native“ Apps für die Plattformen iOS und Android zu erstellen. Doch auch auf Ebene des Unternehmens resultieren dadurch zahlreiche direkte Vorteile, wenn bisher bereits mit .NET entwickelt wurde.

Vorteile der Xamarin-Entwicklung für Unternehmen

  • Kostensenkung durch Reduktion der Technologien und folglich Skills (C#, Xcode, XML).
  • Schutz der bereits getätigten Investitionen durch Weiterverwendung bewährter Konzepte, Werkzeuge und Prozesse der .NET-Entwicklung.
  • Job-Enrichment für Entwickler durch mehrere parallele Zielplattformen.
  • Reduktion der Zeit bis zur Marktreife durch Wiederverwendung von Komponenten und einer möglichen Parallelisierung der Entwicklung (z. B. UI für iOS und Android, nachdem gemeinsame Logik steht).
  • Präsenz in beiden App-Stores, was insbesondere fürs Marketing und die Monetisierung von entscheidender Bedeutung sein kann.

Kommentare (3)

Avatar

Lelala

7 Dezember 2013 um 16:05

Kann man den UI Code zwischen Droid und iOS portieren oder muss man den jeweils neu/extra schreiben? Grüßé

    Oliver Brack

    Oliver Brack

    7 Dezember 2013 um 19:40

    Der UI-Code muss für jede Plattform separat geschrieben werden. Natürlich kann man dafür auch UI-Designer-Tools verwenden, die einem einen Grossteil der Arbeit abnehmen.

    Diesbezüglich könnte für dich auch MvvmCross interessant sein, da sich damit der Code bis hinauf zu den ViewModels (MVVM-Pattern) teilen lässt.

Avatar

Jürgen Grothe

2 September 2016 um 10:11

Gute Beschreibung der Entwicklungsseite, für die Businessseite und mit etwas mehr allgemeinen Informationen habe ich hier https://www.thisisdmg.com/serie-entwicklung-xamarin/ etwas gebloggt.

×

Updates

Schreiben Sie sich jetzt ein für unsere zwei-wöchentlichen Updates per E-Mail.

This field is required
This field is required
This field is required

Mich interessiert

Select at least one category
You were signed up successfully.

Erhalten Sie regelmäßige Updates zu neuen Blogartikeln

Jetzt anmelden

Oder möchten Sie eine Projektanfrage mit uns besprechen? Kontakt aufnehmen »