Ein Hybrid für alle Geräte

Cordova und die Integration in Visual Studio
Kommentare

Apache Cordova erlaubt die Entwicklung hybrider Multideviceanwendungen, die auf Geräteressourcen wie Sensoren, Kalender oder Kontakte zugreifen können. Die neue Visual-Studio-Integration macht diese Plattform .NET-Entwicklern zugänglicher.

In Zeiten wie diesen, wo es immer mehr Endgeräte zu unterstützen gilt und die Entwicklung des Markts nicht vorhersehbar ist, stellen webbasierte Anwendungen mehr denn je eine sehr attraktive Alternative zu ihren nativen Gegenstücken dar. Allerdings können Webanwendungen nur beschränkt mit dem verwendeten Endgerät kommunizieren. Zugriffe auf das Dateisystem, den Kalender oder das Adressbuch sind für Webanwendungen beispielsweise nicht oder nur über Umwege möglich. Auch wenn das W3C an Standards arbeitet, die genau das ermöglichen sollen, wird es noch eine Weile dauern, bis diese flächendeckend umgesetzt sind. Hybridanwendungen meistern diese Herausforderungen hingegen schon heute, indem sie eine Webanwendung innerhalb einer nativen Anwendung ausführen und so der Webanwendung mittels JavaScript Zugriff auf das jeweilige Gerät gewähren. Eine sehr populäre und auch freie Entwicklungsplattform für Anwendungen dieser Art stellt Apache Cordova dar. Sie bildet unter anderem die Basis für die wohl noch populärere Plattform Adobe PhoneGap und unterstützt eine Vielzahl mobiler Plattformen. Trotz eines großen Funktionsumfangs erscheint Cordova mit seinem Commandline-Interface nicht zwangsweise handsam – schon gar nicht für Entwickler, die sich an komfortable IDEs gewöhnt haben. Die von Microsoft auf der TechEd im Mai 2014 vorgestellte Visual-Studio-Integration soll das ändern. Der vorliegende Artikel bietet anhand dieses Werkzeugs eine Einführung in die Welt von Cordova.

Visual Studio: Erstellen einer Cordova-Anwendung

Um die aktuelle Vorabversion der Cordova-Unterstützung für Visual Studio 2013 auszuprobieren, installiert der Entwickler die so genannten „Multi-Device Hybrid Apps (Preview)“. Damit das funktioniert, muss auf dem Rechner bereits Update 2 von Visual Studio 2013 installiert sein. Ist das nicht der Fall, kann der Entwickler Update 2 hier oder über den Erweiterungsmanager in Visual Studio beziehen. Nach der Installation der Cordova-Unterstützung stehen zwei neue Projektvorlagen zur Verfügung – eine sieht den Einsatz von JavaScript vor, die andere verwendet stattdessen TypeScript. Diese Projektvorlagen befinden sich im Visual-Studio-Dialog, der zum Erzeugen neuer Projekte verwendet wird, unter JavaScriptMulti Device Hybrid-App oder TypeScriptMulti Device Hybrid-App, wobei diese Ordner je nach Konfiguration ggf. unterhalb von „Andere Sprachen“ zu finden sind. Projekte, die mit einer dieser beiden Projektvorlagen erstellt werden, weisen die in Abbildung 1 gezeigte Struktur auf. Der Ordner „merges“ beinhaltet Dateien, die für eine bestimmte Zielplattform gedacht sind. Eine Datei mergesandroidcssoverrides.css wird beispielsweise im Zuge des Kompilierens für Android nach cssoverrides.css kopiert. Existiert diese Datei dort bereits, wird sie überschrieben. Plattformspezifische Ressourcen, die für Cordova eine bestimmte Bedeutung haben, legt der Entwickler hingegen unter „res“ ab. Dies betrifft Icons für die Zielplattformen in verschiedenen Größen, aber auch Startbildschirme und Entwicklerzertifikate, die z. B. für die Entwicklung auf der Android-Plattform notwendig sind. Die erwarteten Dateinamen und Eigenschaften werden in der Dokumentation von Cordova sowie in der von Microsoft bereitgestellten Dokumentation gelistet. Ebenfalls Cordova-spezifisch ist die Datei config.xml, die sich im Hauptverzeichnis der Anwendung befindet. Diese beinhaltet Informationen wie z. B. den anzuzeigenden Namen der Anwendung oder die Startseite, bei der es sich standardmäßig um index.html handelt. Ebenfalls in dieser Datei zu finden sind die Versionsnummer, die Orientierung (Hochformat, Querformat oder beides) sowie einzubindende Plug-ins. Daneben trägt der Entwickler in dieser Datei auch die Domänen ein, auf die die Anwendung zugreifen darf. Um den Entwickler zu unterstützen, existiert für diese XML-Datei ein grafischer Editor. Diesen Editor startet Visual Studio, wenn der Entwickler die config.xml öffnet. Möchte er die Datei hingegen als XML-Datei bearbeiten, wählt er die Option Code anzeigen aus ihrem Kontextmenü. Abgesehen von den bis dato besprochenen Ordnern und der config.xml handelt es sich bei einer Cordova-Applikation um eine ganz normale, auf HTML, JavaScript und CSS-basierende Webanwendung. Der Entwickler kann somit die Frameworks seiner Wahl nutzen, beispielsweise jQuery oder AngularJS. Beim Einsatz von Frameworks ist jedoch darauf zu achten, dass Windows 8 bestimmte DOM-Manipulationen nicht erlaubt. Aus diesem Grund sollte der Entwickler zu Frameworkversionen greifen, die einen Patch für Windows 8 enthalten.

Abb. 1: Struktur eines Cordova-Projekts

Auf Geräte über Plug-ins zugreifen

So richtig interessant wird der Einsatz von Cordova, wenn der Entwickler APIs nutzt, die in herkömmlichen Browseranwendungen (noch) nicht zur Verfügung stehen. Dazu gehören APIs zum Zugriff auf Bewegungssensoren, das Dateisystem, Kontakte oder die integrierte Kamera. Diese APIs werden unter Cordova über Plug-ins bereitgestellt. Plug-ins beinhalten nativen Code für einzelne Plattformen sowie eine JavaScript-Fassade, die an den nativen Code delegieren. Somit muss sich der Entwickler nicht um die Unterschiede der einzelnen Plattformen kümmern. Stattdessen nutzt er die von der Fassade angebotenen Funktionen. Er ist jedoch gut beraten, vor dem Einsatz eines Plug-ins in Erfahrung zu bringen, welche Plattformen es unterstützt. Um ein Plug-in zu nutzen, referenziert der Entwickler es über die config.xml. Der Dialog, der den Inhalt der config.xml anzeigt, stellt hierzu einige Plug-ins zur Auswahl (Abb. 2). Alle Plug-ins, die der Entwickler hier aktiviert, werden von Visual Studio beim nächsten Start der Anwendung aus der Apache Cordova Plugins Registry heruntergeladen, sofern dies nicht schon geschehen ist. Standardmäßig gibt Visual Studio die zu verwendende Plug-in-Version vor. Damit möchte Microsoft Versionskonflikte verhindern. Will der Entwickler hingegen eine bestimmte Version eines Plug-ins nutzen, muss er das manuell in die config.xml eintragen. Dasselbe gilt, wenn er Plug-ins aus der Apache Cordova Plugins Registry nutzen möchte, die nicht über den Dialog angeboten werden.

Eine Dokumentation für diese Plug-ins findet sich in der Apache Cordova Plugins Registry. Für jene Plug-ins, die direkt zu Cordova gehören, finden sich entsprechende Informationen auch im Rahmen der Cordova-Dokumentation. Zur Demonstration zeigt Listing 1, wie eine Cordova-Anwendung mit dem Plug-in „Contacts“ einen neuen Kontakt zum Adressbuch des Benutzers hinzufügen kann. Nachdem es einzelne Teile des Kontakts in Form von zwei ContactField-Objekten und einem ContactAddress-Objekt erzeugt hat, kreiert das betrachtete Listing mit der Funktion navigator.contacts.create ein Contact-Objekt. Dieses weist einen Display-Name auf sowie Arrays mit E-Mail-Adressen, Telefonnummern und Adressen, wobei diese Arrays jeweils nur einen Eintrag erhalten. Die von Contact angebotene Funktion save speichert den erzeugten Kontakt im Adressbuch. Da dies asynchron erfolgt, sind zwei Callbacks zu registrieren – einer für den Erfolgsfall und einer für den Fehlerfall.

Abb. 2: Plug-ins in Visual Studio hinzufügen

var email = new ContactField();
email.pref = true;
email.value = "max@muster.com";

var phone = new ContactField();
phone.pref = true;
phone.value = "0000 1111 2222";

var addr = new ContactAddress();
addr.streetAddress = "Milchstrasse 42";
addr.postalCode = "12345";
addr.locality = "Galaxy";

var c = navigator.contacts.create({ 
    displayName: "Max Muster", 
    emails: [email], 
    phoneNumbers: [phone], 
    addresses: [addr] });
c.save(
  function (savedContact) { alert("OK!"); },
  function (error) { alert("Fehler!"); });

Listing 2 stellt das Gegenstück zu Listing 1 dar. Es demonstriert, wie eine Anwendung nach Kontakten im Adressbuch suchen kann. Am Ende ruft es hierzu die Funktion navigator.contacts.find auf, um nach Kontakten zu suchen, die im Namen oder Anzeigenamen (displayName) den Wert Max aufweisen. Auch das Suchen nach Kontakten gestaltet sich asynchron und somit muss der Entwickler auch hier mit Callbacks arbeiten. Der Callback für den Erfolgsfall nimmt ein Array mit den gefundenen Kontakten entgegen, iteriert es und blendet ausgewählte darin zu findende Informationen in der aktuellen Seite ein.

function onError(contactError) {
  alert('Fehler!');
};

function onSuccess(contacts) {
  var txt = "";
  for (var i = 0; i < contacts.length; i++) {
    txt += contacts[i].displayName + " ";
  }
  document.getElementById("info").innerHTML = txt;
};

var options = new ContactFindOptions();
options.filter = "Max"; 
options.multiple = true;
var fields = ["displayName", "name"];

navigator.contacts.find(fields, onSuccess, onError, options);

Aufmacherbild: Photo manipulation: pineapple with watermelon content von Shutterstock / Urheberrecht: PhotoGraphyca

[ header = Seite 2: Weitere Plug-ins verwenden ]

Weitere Cordova Plug-ins verwenden

Neben den vielen Plug-ins, die der Entwickler über die Apache Cordova Plugins Registry beziehen kann, bietet das Open-Source-Umfeld noch eine Menge weiterer Plug-ins. Ein Beispiel dafür ist das hier zu findende SQLightPlugin, das Unterstützung für eine clientseitige Speicherung strukturierter Daten unter Android, iOS und Windows Phone bietet. Im Gegensatz zu „Browserdatenbanken“ wie WebDB und IndexedDB, die ebenfalls über Plug-ins in Cordova-Projekten genutzt werden können, weist dieses Plug-in keine Größenbeschränkung auf.

Um solch ein Plug-in zu nutzen, legt der Entwickler im Hauptverzeichnis der Anwendung einen Ordner „plugins“ sowie darunter einen Ordner für das zu nutzende Plug-in an. In diesen Ordner kopiert er anschließend die Programmdateien des Plug-ins. Die Datei plugin.xml, die das Plug-in mitsamt der für die einzelnen Plattformen vorgesehenen Programmdateien beschreibt, wird direkt in diesem Ordner erwartet (Abb. 3). Dies bewirkt, dass Visual Studio und Cordova das Plug-in gemeinsam mit der Anwendung kompilieren.

Abb. 3: Plug-ins direkt einbinden

Damit der Entwickler über die Anwendung auf das Plug-in zugreifen kann, muss er die JavaScript-Fassade einbinden, die Teil des Plug-ins ist. Im Falle des betrachteten SQLightPlugins findet sich diese Fassade im Ordner „www“ und nennt sich SQLightPlugin.js. Ein Beispiel für den Einsatz dieser Fassade findet sich in Listing 3. Die Funktion sqlightDemo öffnet mit window.sqlitePlugin.openDatabase eine Datenbank namens DB und führt anschließend auf dieser Datenbank mit transaction eine Transaktion durch. Die an transaction übergebene Funktion ist für die Datenbankzugriffe innerhalb dieser Transaktion zuständig. Dazu stützt sie sich auf die Funktion executeSql, die einen SQL-String, ein Array mit Parametern sowie Callbacks für den Erfolgs- und Fehlerfall entgegennimmt. Der SQL-String kümmert sich um das Erzeugen einer Tabelle people. Der Callback für den Erfolgsfall delegiert an savePerson. Diese Funktion fügt mit executeSql eine Person in die Tabelle people ein. IndexedDB ersetzt hierbei die Fragezeichen im SQL-String durch die im Array angeführten Parameter. Im Erfolgsfall kommt die Funktion loadPeople zum Zug. Sie lädt sämtliche Einträge aus der Tabelle people, erzeugt damit ein wenig HTML-Markup und fügt dieses Markup in die aktuelle Seite ein.

function sqlightDemo() {

  var db = window.sqlitePlugin.openDatabase({ name: "DB" });

  db.transaction(function (tx) {

      tx.executeSql(
        "CREATE TABLE IF NOT EXISTS people (id integer primary key, fullName text, age integer)",
        [],
        function () {
          savePerson(db, tx);
        },
        errorCallback);

  });
}

function errorCallback(e) {
  console.log("Fehler: " + e.message);
}

function loadPeople(db) {
  db.transaction(function (tx) {
      tx.executeSql(
        "select *  from people;",
        [],
        function (tx, res) {
          var txt = "";
          for (var i = 0; i < res.rows.length; i++) {
            var row = res.rows.item(i);
            txt += row.fullName + ", " + row.age + " ";
          }

          document.getElementById("info").innerHTML = txt;
        },
        errorCallback);
  });
}

function savePerson(db, tx) {
  tx.executeSql(
    "INSERT INTO people (fullName, age) VALUES (?,?)",
    ["Max Muster", 47],
    function (tx, res) {
      console.log("insertId: " + res.insertId);
      console.log("rowsAffected: " + res.rowsAffected);

      loadPeople(db);
    },
    errorCallback);
}

Emulieren, Testen und Veröffentlichen der Hybrid-Anwendung

Die einfachste Möglichkeit, eine Cordova-Anwendung zu testen, besteht darin, sie in einem Emulator zu starten. Dazu wählt der Entwickler eine Zielplattform und einen Emulator aus. In Abbildung 4 fällt die Wahl beispielsweise auf die Plattform Android sowie auf den Emulator „Ripple – Nexus 7“. Das Feld zur Auswahl der Zielplattform muss bei manchen Visual-Studio-Versionen ggf. erst eingeblendet werden.

Apache Ripple, der im Zuge der Cordova-Unterstützung für Visual Studio installiert wird, ist ein sehr leichtgewichtiger Emulator, der auf Web-Kit-Browser aufsetzt, allen voran Google Chrome. Positiv fällt auf, dass er – im Gegensatz zu anderen Emulatoren, die auf Virtualisierung setzen und nachfolgend als native Emulatoren bezeichnet werden – äußerst schnell geladen ist und auch die wichtigsten Cordova-Plug-ins emuliert. Darüber hinaus kann er eine Vielzahl an verschiedenen Geräten emulieren. Er eignet sich wunderbar, wenn der Entwickler rasch sehen möchte, wie eine Änderung auf dem jeweiligen Zielgerät in etwa aussieht. Allerdings ist zu berücksichtigen, dass Apache Ripple keinesfalls eine komplette Emulation der Zielplattform mit all ihren Möglichkeiten oder von Cordova bietet. Aus diesem Grund ist er kein Ersatz für native Emulatoren und das Testen auf den tatsächlichen Zielgeräten.

Abb. 4: Zielplattform und Emulator wählen

Für eine native Android-Emulation bietet sich die Option Device Emulator an. Diese delegiert an den Android Virtual Device Manager (AVD Manager), der ebenfalls Teil der Installation der hier behandelten Cordova-Werkzeuge ist. Es empfiehlt sich, vor dem Start der Anwendung in Visual Studio den AVD Manager direkt zu starten und über diesen den zu verwendenden Emulator hochzufahren. Startet der Entwickler danach die Anwendung in Visual Studio, verwendet Visual Studio diesen Emulator.

Beschleunigen von Android-Emulatoren Native Android-Emulatoren sind nicht gerade für ihre Geschwindigkeit bekannt. Allerdings existieren ein paar Kniffe, um diese zu beschleunigen. Informationen dazu finden sich hier.

Der gewünschte Emulator muss jedoch zunächst im AVD Manager erzeugt werden. Dazu lädt sich der Entwickler zunächst über TOOLS | MANAGE SDK das gewünschte Image herunter und erstellt damit anschließend durch einen Klick auf die Schaltfläche CREATE ein neues zu emulierendes Gerät. Bei der Auswahl eines Images ist darauf zu achten, dass Versionsbezeichner mit der Endung W für „Android Wear“ stehen, das beispielsweise in Smartwatches zum Einsatz kommt. Möchte der Entwickler also ein Smartphone oder ein Tablet emulieren, ist diese Version nicht die erste Wahl. Vielmehr wird der Entwickler dann zur Version Android 4.4.2 oder ihren Nachfolger Android L („Android 5.0“) greifen. Ein Deployment auf ein mit dem Rechner verbundenes Gerät ist ebenfalls möglich. Dazu wählt der Entwickler anstatt eines Emulators den Eintrag „Device“. Das Testen mit nativen Emulatoren für andere Geräte wie iPhone, iPad, Windows Phone oder Windows 8 gestaltet sich ähnlich. Auf iOS-Geräte kann jedoch lediglich über einen Mac zugegriffen werden und auch für die native Emulation von iOS-Geräten ist ein Mac notwendig. Zur Vereinfachung besteht die Möglichkeit, den Entwicklungsrechner mit einem Mac und somit mit einem iOS-Gerät bzw. einem iOS-Emulator zu koppeln. Die nötigen Schritte für das Erzeugen von Paketen zur Verteilung auf Endgeräte unterscheiden sich von Gerät zu Gerät. Informationen hierzu können der Dokumentation entnommen werden.

Fazit

Die Visual-Studio-Integration von Apache Cordova macht den Einsatz dieses populären Frameworks um einiges einfacher. Allerdings darf man derzeit noch nicht davon ausgehen, dass damit die Komplexität für die Entwicklung von Hybridanwendungen auf das Niveau von klassischen Windows- oder Webanwendungen gesenkt wird. Vielmehr muss sich der Entwickler nach wie vor mit den Eigenheiten der einzelnen Plattformen beschäftigen und die Anwendung auch auf den angesprochenen Gerätetypen testen. Auch mit den unterschiedlichen Deployment-Verfahren muss er sich auseinandersetzen. Außerdem hat er zu beachten, dass nicht jedes Plug-in für jede Plattform zur Verfügung steht und dass sich nicht jedes Plug-in auf jeder unterstützten Plattform zwangsweise gleich verhält. Wer bereit ist, diese Herausforderungen auf sich zu nehmen, um Anwendungen für verschiedene Plattformen mit derselben Codebasis zu schreiben, wird hingegen heute schon seine Produktivität mit der Vorabversion der Visual-Studio-Integration steigern können. Darüber hinaus kann davon ausgegangen werden, dass die finale Version einige der genannten Herausforderungen zumindest abschwächen wird.

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -