Cross-Platform

Schreiben von plattformübergreifenden Hybrid-Apps in Visual Studio mit Apache Cordova

Kraig Brockschmidt
Mike Jones

Laden Sie die Codebeispiele herunter

Webentwickler mit Kenntnissen in Standard-HTML, CSS und JavaScript wissen bereits, dass Webanwendungen eine maximale Bandbreite von Geräten und Kunden mit einer einzigen Codebasis erreichen. Und mit reaktionsfähigem Webdesign (RWD, Responsive Web Design) können Webanwendungen auch großartige Erfahrungen auf mobilen Geräten liefern.

Doch der Wind scheint sich gedreht zu haben: Daten zeigen, dass mobile Kunden ca. 80 % Ihrer Zeit mit Apps und 20 % mit Browsern verbringen. Einfach gesagt heißt das, dass selbst die besten mobilen Weblösungen einfach nicht dieselbe Sichtbarkeit und Nutzung erfahren wie systemeigene Apps, die über Plattform-App Stores auffindbar sind. Darüber hinaus handelt es sich, obgleich sich W3C und Browserhersteller mithilfe neuer HTML5-Standards ständig bemühen, systemeigene Plattformfunktionen nutzbar zu machen, um einen langsamen Prozess. Im Vergleich zu systemeigenen Apps und systemeigenen APIs sind das mobile Internet und HTML5 grundsätzlich im Nachteil, wenn es darum geht, Kunden durch Innovationen zu erfreuen.

Müssen Sie also jetzt in den sauren Apfel beißen und systemeigene Apps schreiben? Müssen Sie verschiedene Sprachen und Benutzeroberflächenparadigmen lernen, die hohen Kosten der Verwaltung von Projekten für jede Plattform schultern und infolge dessen potenzielle Marktchancen verpassen?

Überhaupt nicht! Betreten Sie die Welt des Open Source-Frameworks, bekannt als Apache Cordova (cordova.apache.org), das von der Apache Software Foundation (ASF) verwaltet wird. Mit Cordova können Sie Ihre HTML-, CSS- und JavaScript-Fertigkeiten nutzen – plus umfangreiche Communityressourcen – um Apps für Android, Amazon Fire, iOS, Mac OS X, Windows, Windows Phone, BlackBerry, Webbrowser und mehr zu erstellen. Noch besser: Während Webanwendungen nur über begrenzte von Browsern unterstützte Funktionen verfügen, bietet das Plug-In-Modell von Cordova vollen Zugriff auf systemeigene Plattform-APIs.

Somit verschafft Ihnen Cordova die plattformübergreifenden Vorteile des Internets, ohne dabei Funktionalität zu opfern, und bietet einen attraktiven Weg, um in den Markt für mobile Apps vorzudringen. Wir zeigen Ihnen, wie das alles funktioniert, indem wir die einfache Selfie-App erstellen, die in Abbildung 1 zu sehen ist.

Die "Here My Am!"-App auf einem Android-Gerät
Abbildung 1 Die "Here My Am!"-App auf einem Android-Gerät

Cordova in Visual Studio

Das Arbeiten mit Cordova erfolgt normalerweise über den Knotenpaket-Manager (npm, Node Package Manager) und die Cordova-Befehlszeilenschnittstelle (CLI). Je nach Zielplattform müssen Sie noch weitere Komponenten wie Plattform-SDKs installieren, wie im Abschnitt "Platform Guides" der Apache Cordova-Dokumentation (bit.ly/1tJ19fq) beschrieben. Für viele Entwickler, die für Android, iOS und Windows programmieren, kann dies eine Menge Arbeit bedeuten, und es kann einige Zeit dauern, all die Feinheiten der verschiedenen Tools zu erlernen.

Um dies zu erleichtern und die Leistungsfähigkeit und Produktivität von Visual Studio in Cordova zu integrieren, erstellt Microsoft die Visual Studio Tools für Apache Cordova. Dieses Toolkit, zurzeit im Preview-Stadium und als Erweiterung für Visual Studio 2013 Update 4 erhältlich (bit.ly/11m4vKH) sowie integriert in Visual Studio 2015 Preview (bit.ly/1u1dsSQ), installiert und konfiguriert alle Drittanbieterabhängigkeiten für Android- und iOS-Ziele korrekt (Windows ist automatisch in Visual Studio enthalten). Anschließend automatisiert es Cordova-Prozesse in der Visual Studio-IDE, z. B. das Installieren von Plug-Ins, das Erstellen von Builds und das Bereitstellen auf Geräten und Emulatoren. Darüber hinaus verschafft es Ihnen all die Vorteile, die Sie von Visual Studio erwarten, wie IntelliSense, integriertes Debuggen, Projekt- und Konfigurationsmanagement, Integration in Visual Studio Online und die Möglichkeit zur Verwendung von TypeScript.

Um für Android- und Windows-Ziele mithilfe von Visual Studio zu entwickeln, benötigen Sie nur einen Computer unter Windows 8 oder höher (und für Android können Sie auch unter Windows 7 entwickeln). Mit iOS als Ziel benötigen Sie einen Mac mit Xcode 5.1 oder höher, und Sie können Visual Studio in Windows auf Parallels oder in VMware Fusion ausführen. (Details hierzu finden Sie auf der MSDN Library-Seite "Install Tools to Build for iOS" unter bit.ly/1GqnEuK, einschließlich Informationen zum Remote-Build-Agent, "vs-mda-remote", der auf Macs ausgeführt wird und Ihnen ermöglicht, aus Visual Studio über ein lokales Netzwerk oder eine VPN-Verbindung Builds zu erstellen, Code auszuführen und diesen zu debuggen.)

Webhosts und reaktionsfähige, browserübergreifende CSS

Wir nennen unsere Selfie-App "Here My Am!" (ein Ausdruck, den Kraigs Sohn mit 3 Jahren geprägt hat), und ihr HTML5-Markup ist ganz geradlinig, wie Sie in Abbildung 2 sehen können.

Abbildung 2 Das HTML-Markup der "Here My Am!"-App

<body>
  <div class="mainContainer">
    <div class="title mainChild">
      <h1 class="titlearea ">Here My Am!</h1>
    </div>
    <div id="locationSection" class="mainChild subsection">
      <h2 class="section-title">Here:</h2>
        <div id="locationControls">
          <input id="txtLocation" type="text" placeholder="tap to edit" />
            <button id="btnLocate" class="iconGlobe"></button>
        </div>
    </div>
    <div id="photoSection" class="mainChild subsection">
      <h2 id="photoHeading" class="section-title">My:</h2>
        <div id="photo">
          <img id="photoImg" src="#" draggable="false"
          alt="Tap to capture image from camera" />
        </div>
    </div>
    <div id="shareSection" class="mainChild">
      <button id="btnShare" class="shareButton" disabled>Share</button>
    </div>
  </div>
</body>

Als Nächstes benötigen wir die geeignete Formatierung, damit es wie in Abbildung 1 aussieht, was uns die Gelegenheit gibt, das Wesen der Natur von Cordova zu ergründen.

Systemeigene mobile Apps werden im Allgemeinen aus kompilierten ausführbaren Dateien ausgeführt: Der Code, den Sie in Sprachen wie Objective-C, Swift, Java, C# und C++ schreiben, wird in Binärformate kompiliert, die mobile Betriebssysteme interpretieren können. Andererseits müssen HTML, CSS und JavaScript an einen Host, z. B. einen Browser, übergeben werden, der diesen Quellcode zur Laufzeit analysiert, rendert und ausführt. Einige Plattformen wie Windows 8/8.1 und Windows Phone 8.1 bieten einen Host auf Systemebene, der HTML, CSS und JavaScript direkt als systemeigene App rendert. Weitere Informationen hierzu finden Sie in dem kostenlosen E-Book "Programming Windows Store Apps with HTML, CSS, and JavaScript, Second Edition" (Microsoft Press, 2014) von Kraig Brockschmidt unter bit.ly/1jyOYLC. Cordova verwendet, wann immer möglich, eine solche Funktion. Andernfalls verwendet es, wie zurzeit unter iOS und Android, ein browserähnliches WebView-Element in einem systemeigenen App-Wrapper, wie in Abbildung 3 dargestellt. In beiden Fällen haben Sie eine Umgebung, in der Ihr webstandardkonformer Code im Kontext einer App ausgeführt wird.

Cordova führt HTML, CSS und JavaScript in einer systemeigenen App-Umgebung aus
Abbildung 3 Cordova führt HTML, CSS und JavaScript in einer systemeigenen App-Umgebung aus

Der Haken an der Sache ist, dass diese Hostumgebungen nicht in der gleichen Form erstellt werden. Jede ist eine Variante des systemeigenen Browsers im Betriebssystem, wie in Abbildung 4 gezeigt.

Abbildung 4 Basis für Hostumgebungen

Mobile Plattform Hostbasis
Windows 8/8.1, Windows Phone 8/8.1 Internet Explorer 10/11
Android 4.x, 5.0 Android Browser 4.x, 5.0 (4.4 oder höher wird für eine optimale Implementierung empfohlen)
iOS7, iOS8 iOS Safari 7.1/8 oder höher, je nach Updates

Deshalb muss das CSS einer Cordova-App auf dem Webhost jeder Zielplattform funktionieren, genau wie Webanwendungen in verschiedenen Browsern funktionieren müssen, indem verschiedene Formatvorlagen mit und ohne Präfixe verwendet wird, wobei Sie ähnliche Ansätze verwenden können. Es ist beispielsweise hilfreich, die Dateien Ihrer App auf einem Webhost abzulegen und sie in Internet Explorer, Chrome oder Safari (auf einem Mac) zu öffnen und dann mithilfe von Browserentwicklertools Ihre Formatierungen bei unterschiedlichen Fenstergrößen zu testen. Überprüfen Sie Ihre Formatierungen auch noch einmal auf caniuse.com, wo genau identifiziert wird, welche HTML5- und CSS3-Funktionen in welchen Browsern und mobilen Umgebungen unterstützt werden (und denken Sie daran, sich insbesondere den Android Browser und iOS Safari anzusehen). Natürlich lassen sich einfachere Layouts besser anpassen, und Sie können CSS-Frameworks wie jQuery Mobile, Ionic und Bootstrap verwenden. Sie können auch CSS-Präprozessoren wie LESS oder SASS verwenden, die seit Visual Studio 2013 Update 2 unterstützt werden, aber vor einem Cordova-Build ausgeführt werden müssen.

Ähnlich hierzu treffen mobile Apps ebenfalls auf zahlreiche Kombinationen aus Bildschirmgröße und -ausrichtung, wie in Abbildung 5 gezeigt.

Abbildung 5 Gängige Bildschirmgrößenkombinationen

Hochformatbreite/Querformathöhe Hochformathöhe/Querformatbreite
240 (Telefone der unteren Kategorie) 320, 400, 480
320 (Telefone der mittleren Kategorie) 462, 480, 470, 568 und höher unter Windows in einer schmalen Ansicht
480 (Telefone der mittleren Kategorie) 640, 800, 854 und andere Höhen unter Windows in einer Hochformatausrichtung mit mehr als 500 Pixel
720, 768 (Tablets) 960, 1024 oder größer. Das iPad hat 1024x768, ebenso einige Ansichten unter Windows.
Größer als 768 iPad 2 und höher. Die meisten Windows-Laptops und -Tablets und viele Android-Tablets

Alle Prinzipien des reaktionsfähigen Webdesigns – die Verwendung von Medienabfragen zum Anpassen von Rändern, Schriftgraden, Layouts, Animationen usw. – sind somit auch bei Cordova-Apps von wesentlicher Bedeutung (und um die Sache einfach zu halten, unterstützt die "Here My Am!"-App nur den Hochformatmodus). Bedenken Sie auch, dass die physischen Bildschirmabmessungen eines Geräts nicht notwendigerweise mit denen übereinstimmen, die an das CSS-Renderingmodul gemeldet werden. Bei hoch auflösenden Displays (DPI) wird normalerweise ein Skalierungsfaktor angewendet, was bedeutet, dass sich die Größenangaben in Abbildung 5 eher auf [min | max]-[width | height]-Medienabfragen beziehen, als auf [min | max]-device-[width | height]-Abfragen. In einigen Fällen ist die Skalierung eventuell auch nicht exakt. Eine nominale Abmessung von 768 Pixel auf einem iPad kann in CSS als 767 dargestellt werden. Testen Sie früh genug und oft, und erwägen Sie auch hier wieder den Einsatz eines CSS-Frameworks oder Präprozessortools.

Die Cordova-App-Projektstruktur

Nachdem sich unser Markup und CSS nun sehen lassen können, können wir Sie in einer Cordova-App vereinen. In Visual Studio ergibt eine Cordova-App, die über "Datei | Neu | Projekt" erstellt wurde, wenn "JavaScript | Apache Cordova-Apps | Leere App (Apache Cordova)" ausgewählt wird, die in Abbildung 6 dargestellte Projektstruktur (beachten Sie, dass sich diese ändern kann, je näher RTM für die Tools für Cordova heranrückt).

Abbildung 6: Projektstruktur in Visual Studio

Ordner oder Datei Umbenennen möglich? Beschreibung
css Ja Ordner oder Stylesheets. Die Ordner "css", "images" und "scripts" können alle beliebig umbenannt werden, und Sie können aus Ihren HTML-Dateien darauf verweisen.
images Ja Standardordner (leer) für plattformneutrale Grafiken.
merges Nein Ordner für plattformspezifisches JavaScript. Die Buildtools sind von diesem Ordnernamen, wie von "res", abhängig.
res Nein Ordner für plattformspezifische Ressourcen wie Symbole, Begrüßungsbildschirme und Manifeste.
scripts Ja Standardordner für JavaScript-Dateien.
config.xml Nein Die globale Konfigurationsdatei, die mit der W3C-Spezifikation für gepackte Web-Apps (Packaged Web Apps, Widgets) konform ist. Sie dient als generisches Manifest, dessen Einstellungen in plattformspezifische Manifesteinträge übersetzt werden. Visual Studio bietet einen Designer für "config.xml", und Sie können die XML-Rohdaten bearbeiten, da einige Einstellungen im Designer nicht angezeigt werden.
index.html Ja Standardstartseite für die App, auf die im Feld "Common | Start Page" von "config.xml" verwiesen wird. Wenn Sie sie umbenennen, müssen Sie "config.xml" entsprechend aktualisieren.

Für unsere App legen wir das Markup in "index.html" ab und unser Formatvorlagen in "css/index.css". Wegen verschiedener Zusatzfunktionen binden wir außerdem die plattformübergreifende WinJS 3.0-Bibliothek ein, die wir in "css/frameworks", "css/fonts" und "scripts/frameworks" kopiert haben, damit alles schön übersichtlich bleibt (und natürlich können Sie eine beliebige Anzahl weiterer Bibliotheken wie AngularJS oder Bootstrap verwenden). Im Folgenden sehen Sie das <head>-Element aus "index.html":

<!-- Recommended to prevent pinch zoom in webviews -->
<meta name="viewport" content="user-scalable=no" />
<link href="css/frameworks/ui-dark.css" 
  rel="stylesheet" /> <!-- WinJS -->
<link href="css/index.css" rel="stylesheet" /> <!-- App styles -->
<script src="cordova.js"></script> <!-- Cordova standard -->
<!-- WinJS -->
<script src="scripts/frameworks/base.js"></script>
<script src="scripts/frameworks/ui.js"></script>
<script src="scripts/frameworks/winjs.js"></script>
<!-- Project references -->
<script src="scripts/platformOverrides.js"></script>
<script src="scripts/index.js"></script>

Beachten Sie den Verweis auf "cordova.js", das Sie nirgendwo im Projekt finden werden, da es automatisch im Rahmen des Buildprozesses eingebunden wird.

Was "platformOverrides.js" betrifft, ist die Datei dieses Namens im Stammordner "scripts" leer, aber es gibt noch eine in "merges/windows/scripts", die eine andere Datei namens "winstore-jscompat.js" lädt (um die Einbindung von Drittanbieterbibliotheken zu vereinfachen). Zur Buildzeit werden alle Dateien und Ordner unter "merges/<Plattform>" in die endgültige Ordnerstruktur kopiert, wobei alle Dateien mit denselben Namen im Stammprojekt überschrieben werden. Unter Windows wird "scripts/platformOverrides.js" durch "merges/windows/scripts/platformoverrides.js" ersetzt. Auf diese Weise können Sie, falls erforderlich, plattformspezifischen Code integrieren, und dieselbe Zusammenführung auf Dateiebene funktioniert auch für CSS, Bilder und alle anderen Elemente. Denken Sie nur daran, dass es sich um eine Zusammenführung auf Dateiebene handelt, keine Zusammenführung von Dateiinhalten! Beachten Sie außerdem, dass der Ordner "merges" zugunsten von Ansätzen mit Funktionserkennung eventuell nicht mehr unterstützt wird.

Der Inhalt des Ordners "res" besitzen ein ähnliches aber vielfältigeres Verhalten, weil diese Ressourcen für das App-Paket benötigt werden, statt für den Code, der in der WebView oder auf dem Host ausgeführt wird. Denken Sie daran, dass Cordova nötigenfalls einen systemeigenen App-Wrapper um die WebView herum erstellt, was bedeutet, dass es eine Ordnerstruktur für das systemeigene App-Paket erstellt, wie sie für die Zielplattform erforderlich ist. Abbildung 7 illustriert, wo verschiedene Teile des Visual Studio-Projekts in einem Build platziert werden. Sie können die Ergebnisse anzeigen, wenn Sie ein Projekt erstellen und dann den Ordner "bld/debug/platforms" öffnen. Wir nutzen dieses Verhalten später, um die Windows/Windows Phone-App-Manifeste anzupassen.

Verteilung verschiedener Teile eines Quellprojekts in plattformspezifische Buildordner (kann sich ändern)
Abbildung 7 Verteilung verschiedener Teile eines Quellprojekts in plattformspezifische Buildordner (kann sich ändern)

Systemeigene APIs und Plug-Ins

Jetzt sind wir bereit, um unserer App Verhalten in JavaScript hinzuzufügen. Standardmäßig stellt die Cordova-App-Vorlage in Visual Studio den in Abbildung 8 gezeigten Code bereit (ohne die meisten Kommentare), wobei die Cordova-Ereignisse "deviceready", "pause" und "resume" auf verschiedenen Plattformen ähnliche App-Lebenszyklusereignisse abstrahieren (die vollständige Liste finden Sie im Abschnitt "Events" der Apache Cordova-Dokumentation unter bit.ly/1u1hT1n).

Abbildung 8 Standardcode aus der Cordova-App-Vorlage

(function () {
  "use strict";
  document.addEventListener('deviceready', 
    onDeviceReady.bind(this), false);
  function onDeviceReady() {
    document.addEventListener('pause', onPause.bind(this), false);
    document.addEventListener('resume', onResume.bind(this), false);
    // Perform other initialization here.
  };
  function onPause() {
  };
  function onResume() {
  };
} )();

Zur Vereinfachung werden keine Daten in "Here My Am!" dauerhaft gespeichert, weshalb wir die "pause"- und "resume"-Handler entfernt haben.

Beachten Sie, dass "deviceready" normalerweise nach "DOMContentLoaded" ausgelöst wird, sodass Sie DOM-bezogene Initialisierungen innerhalb Ihres "deviceready"-Handlers ausführen können. In manchen Debuggingszenarios, wie z. B. bei der Verwendung von Visual Studio-Remotedebugging über ein WLAN, ist es jedoch möglich, dass "deviceready" vor "DOMContentLoaded" ausgelöst wird, was "Null-Objekt"-Ausnahmen verursacht. "Here My Am!" verwendet einige Kennzeichen zur Verarbeitung dieser Variabilität.

Folgendes müssen wir nun in unserer App machen:

  • Das "Here"-Feld mit dem Standort des Benutzers initialisieren und die "Locate"-Schaltfläche verknüpfen.
  • Den Fotobereich mit der Standardmeldung initialisieren und mit der Kameraerfassung verknüpfen.
  • Das Teilen von Standort und Foto ermöglichen.
  • Die Displayausrichtung auf Hochformat sperren.

Zwar könnten wir die HTML5-Geolocation-API verwenden und eine Menge Code schreiben, um mit bestimmten sozialen Netzwerken zu teilen, doch beginnen wir Probleme mit der Kameraerfassung zu bekommen, weil es zwei primäre Einschränkungen von WebView gibt, die sich auf die Cordova-Entwicklung auswirken können (z. B. auf iOS und Android):

  1. WebViews blockieren den Zugriff von JavaScript auf alle systemeigenen Plattform-APIs, weil nicht vertrauenswürdiger JavaScript-Code, der von einer potenziellen Remotequelle geladen wird, ein Sicherheitsrisiko darstellt. (Auf Windows-Plattformen wird paketinternem JavaScript vertraut, und es kann systemeigene APIs aufrufen, aber remote geladener Script-Code kann dies nicht.)
  2. WebViews unterstützen normalerweise nur eine Teilmenge von HTML5-APIs (je nach Plattform unterschiedlich, siehe caniuse.com), und viele systemeigene Funktionen sind weit davon entfernt über passende HTML5-Standards zu verfügen.

Glücklicherweise können eine systemeigene App und alle darin enthaltenen WebViews über spezielle, vom Betriebssystem bereitgestellte Mechanismen miteinander kommunizieren. Cordova abstrahier diese Mechanismen mithilfe von Plug-Ins, wie in Abbildung 9 dargestellt. Einfach gesagt, enthält ein Plug-In eine universelle JavaScript-Schnittstelle, die in die WebView geladen wird, die wiederum den Kommunikationskanal der Plattform verwendet, um mit einem Teil systemeigenen Codes zu kommunizieren, der für diese Plattform kompiliert wurde und systemeigene APIs verwenden kann. Auch hier ist es, wo die zugrunde liegende Plattform systemeigene JavaScript-Apps unterstützt, nicht notwendig, eine solche Überbrückung zu verwenden, doch Plug-Ins dienen immer noch der Abstraktion von Plattformunterschieden.

Die Struktur von Cordova-Plug-Ins, wenn eine Überbrückung erforderlich ist, wie bei iOS oder Android
Abbildung 9 Die Struktur von Cordova-Plug-Ins, wenn eine Überbrückung erforderlich ist, wie bei iOS oder Android

Die ASF stellt einen Kernsatz von Cordova-Plug-Ins für gängige, systemeigene APIs bereit, z. B. Speicher, Medien, Netzwerk, Geolocation, Sensoren Dialoge, Medienerfassung, Benachrichtigungen, Geräteinformationen und Globalisierung. Wenn Sie diese Plug-Ins im Visual Studio-Editor für "config.xml" auswählen, wird automatisch der geeignete Code in Ihren Build eingebunden.

Sie können auch im Cordova-Plug-Ins-Katalog (plugins.cordova.io) sowie auf anderen Websites wie plugreg.com sich am reichhaltigen Angebot von Drittanbieter-Plug-Ins bedienen. Diese decken alle Arten von Funktionen ab, einschließlich Werbung, Microsoft Azure Mobile Services, Bluetooth-Kommunikation, Teilen in sozialen Netzwerken und vieles mehr. Und da Plug-Ins nicht zwangsläufig systemeigene APIs einfach nur 1:1 zur Verfügung stellen, steigern Plug-In-Entwickler häufig noch den Wert, indem sie Funktionen auf höherer Ebene erstellen, z. B. Barcodescanner und Integration in Webdienste. Ein großartiges Beispiel ist das Plug-In für Cortana, den Sprach-Assistenten für Windows Phone. Entwickelt von Microsoft Open Technologies Inc., einer 100 %igen Tochter von Microsoft, die sich auf Open Source-Technologien spezialisiert hat, wurde das Plug-In von den Entwicklern gut aufgenommen am PhoneGap Day im Oktober 2014. Bedenken Sie dennoch, dass die Plattformunterstützung stark schwankt bei Plug-Ins. Beispielsweise unterstützt das Cortana-Plug-In nur Windows Phone 8.1.

Wie auch immer, der Visual Studio-Editor für "config.xml" hilft Ihnen dabei, auf einfache Weise Plug-Ins aus Quellen wie dem Cordova-Katalog oder GitHub in Ihr Projekt einzubinden, wie im MSDN Library-Artikel "Manage Plugins for Apps Built with Visual Studio Tools for Apache Cordova" unter bit.ly/10ov6Fo beschrieben. Wir zeigen Ihnen in Kürze ein Beispiel. Visual Studio bindet automatisch die richtigen Dateien ein, sodass die geeigneten Methoden dem globalen Namespace hinzugefügt werden, ohne dass Sie explizit auf die JavaScript-Datei eines Plug-Ins verweisen müssen.

Insgesamt, wenn wir an systemeigene APIs denken, gilt bei Cordova die Konvention, zuerst nach einem geeigneten Plug-In zu suchen, statt Ihrer App plattformspezifischen Code hinzuzufügen. Wenn Sie ein Plug-In finden, das den gewünschten Funktionen nahekommt, sollten Sie erwägen, es zu erweitern. Schließlich sind viele von Entwicklern wie Ihnen geschrieben, und Beiträge sind auf GitHub immer willkommen. Andernfalls lesen Sie im Abschnitt "Plugin Development Guide" der Apache Cordova-Dokumentation nach, wie Sie ein eigenes Plug-In erstellen können, das Sie dann mit der Cordova-Community teilen können.

Fertigstellen der App

Mit dem Wissen, wie wir mittels Plug-Ins auf systemeigene APIs zugreifen können, können wir die Funktionen unserer App zum Abschluss bringen. Für die Geolocation-Funktion binden wir das Plug-In "Cordova Geolocation" ein und fügen diesen Code unserem "deviceready"-Handler hinzu, um das Standortfeld (location) zu initialisieren und die "Locate"-Schaltfläche zu verknüpfen:

locate();
document.getElementById("btnLocate").addEventListener("click", locate);

Dann implementieren wir die locate-Methode, wie in Abbildung 10 dargestellt.

Abbildung 10 Implementieren von Geolocation

function locate() {
  navigator.geolocation.getCurrentPosition(function (position) {
    App.lastPosition = {
      latitude: position.coords.latitude, 
        longitude: position.coords.longitude,
      address: "(" + position.coords.latitude + ", 
        "      + position.coords.longitude + ")"
    };
    // Go translate the coordinates into an address using the Bing Map Web API.
    updatePosition();
  }, function (error) {
    WinJS.log && WinJS.log("Unable to get location: "
     + error.message, "app");
  }, {
    maximumAge: 3000, timeout: 10000, enableHighAccuracy: true
  });
}

Moment mal, ist "navigator.geolocation" nicht einfach die HTML5-API? Mag sein: Das Plug-In verwendet die HTML5-Implementierung intelligent, wenn sie verfügbar ist, andernfalls fügt es dieselben Funktionen zum globalen Namespace hinzu, die mithilfe der systemeigenen APIs implementiert sind (oder schlägt ordnungsgemäß fehl, wenn keine Plattformunterstützung vorhanden ist). Auf diese Weise muss Code, der von einer Website migriert wurde, nicht neu geschrieben werden.

Wenn wir den Standort abgerufen haben, werden die Koordinaten in "App.lastPosition" gespeichert und eine "default App.address"-Standardzeichenfolge erstellt, die für das "txtLocation"-Benutzeroberflächenelement und zum Teilen verwendet wird. Unsere updatePosition-Funktion (nicht abgebildet) versucht dann, die Web-API von Bing Maps zu verwenden, um diese Koordinaten in eine sinnvolle Adresse zu übersetzen, bevor der txtLocation-Wert festgelegt wird. Details hierzu finden Sie im begleitenden Codedownload.

Für die Kameraerfassung erstellen wir anfangs ein Standardbild und verknüpfen den Fotobereich, damit dieser die Erfassung übernimmt:

setPlaceholderImage();
document.getElementById("photo").addEventListener("click",
  capturePhoto.bind(photo));

Durch das Hinzufügen des Cordova Camera-Plug-Ins wird die Methode "naviga­tor.camera.getPicture" dem globalen Namespace hinzugefügt. Falls erfolgreich, stellt dieser Aufruf einen URI zu einem Bild auf dem lokaeln Dateisystem des Geräts bereit, den wir dann einfach einem "img.src"-Attribut hinzufügen können. In dem in Abbildung 11 gezeigten Code erfolgt die Zuweisung innerhalb unserer scaleImageToFit-Funktion, die Letterboxing anwendet, um das Seitenverhältnis des Bilds zu erhalten.

Abbildung 11 Arbeiten mit dem Cordova Camera-Plug-In

function capturePhoto() {
  var photoDiv = this;
  // Capture camera image into a file.
  navigator.camera.getPicture(cameraSuccess, cameraError, {
    quality: 50,
    destinationType: Camera.DestinationType.FILE_URL,
    encodingType: Camera.EncodingType.JPEG,
    mediaType: Camera.MediaType.PICTURE,
    allotEdits: true
    correctOrientation: true // Corrects Android orientation quirks.
  });
  function cameraSuccess(imageFile) {
    // Save for share and enable Share button.
    App.lastCapture = imageFile;
    document.getElementById("btnShare").disabled = false;
    // Do letterboxing and assign to img.src.
    scaleImageToFit(photoDiv.querySelector("img"), 
      photoDiv, App.lastCapture);
  };
  function cameraError(error) {
    WinJS.log && WinJS.log("Unable to obtain picture: " + error, "app");
  };
}

Um die Teilenfunktion zu implementieren, die aktiviert wird, sobald ein Bild vorliegt, haben wir Eddy Verbruggens Plug-in "Social­Sharing" auf plugreg.com gefunden, das sowohl mit Text als auch Bildern funktioniert. Wenn wir es als benutzerdefiniertes Plug-In direkt von GitHub hinzufügen (siehe Abbildung 12), lädt Visual Studio alle benötigten Komponenten automatisch herunter. (Dieser Prozess lädt alles aus dem Repository herunter, aber die einzig wesentlichen Teile sind die "plugin.xml"-Datei des Plug-Ins und die Ordner "src" und "www" – alles andere kann entfernt werden.)

Hinzufügen eines benutzerdefinierten Plug-Ins von GitHub
Abbildung 12 Hinzufügen eines benutzerdefinierten Plug-Ins von GitHub

Jetzt können wir die "Share"-Schaltfläche (Teilen) verknüpfen und die "socialsharing.share"-API des Plug-Ins aufrufen (im Namespace "window.plugin"), um die in Abbildung 13 dargestellte Benutzeroberfläche zu erhalten, die eine Reihe von Auswahlmöglichkeiten zum Teilen bietet, ähnlich dem Charm "Teilen" unter Windows 8/8.1:

document.getElementById("btnShare").addEventListener("click", App.share);
function share() {
  var txtLocation = document.getElementById("txtLocation").value;
  plugins.socialsharing.share("At " + txtLocation, "Here My Am!",
    App.lastCapture);
}

Freigeben unter Android, iOS und Windows Phone 8 (Bilder zur Verfügung gestellt durch das SocialSharing-Plug-In)
Abbildung 13 Freigeben unter Android, iOS und Windows Phone 8 (Bilder zur Verfügung gestellt durch das SocialSharing-Plug-In)

Dabei gibt es jedoch einen Haken: SocialSharing unterstützt Android, iOS und Windows Phone 8, aber nicht Windows 8/8.1 und Windows Phone 8.1. Eine ganze Reihe von Drittanbieter-Plug-Ins besitzen nur eingeschränkte Plattformunterstützung, was tatsächlich eine willkommene Gelegenheit darstellt, an der Verbesserung des Plug-Ins zum Nutzen der Community mitzuwirken. Für diesen Artikel bietet es uns jedoch die Möglichkeit, die Verwendung des Ordners "merges" zu demonstrieren, weil eine Cordova-App unter Windows im Systemhost ausgeführt wird, in dem wir systemeigene APIs direkt aus JavaScript aufrufen und das Plug-In vollständig umgehen können.

Zuerst verschieben wir die zuvor erwähnte Teilenfunktion in eine "share.js"-Datei und stellen Sie als "App.share" zur Verfügung:

WinJS.Namespace.define("App", {
  configurePlatformSharing: function () { },
  share: share
});
function share() {
  var txtLocation = document.getElementById("txtLocation").value;
  plugins.socialsharing.share("At " + txtLocation, "Here My Am!",
    App.lastCapture);
}

Als Nächstes stellen wir in "merges/windows/share.js", womit die plattformneutrale "share.js" ersetzt wird, eine andere "App.share"-Funktion bereit, die den Charm "Teilen" aufruft:

function share() {
  Windows.ApplicationModel.DataTransfer.DataTransferManager.showShareUI();
}

Damit dies funktioniert, müssen wir dennoch während der Initialisierung für das "DataTransferManager.ondatarequested"-Ereignis einen Handler verknüpfen. Dies ist der Zweck der Stubmethode "configurePlatformSharing", die auf Nicht-Windows-Plattformen keine Funktion hat, wenn wir sie im "deviceready"-Handler aufrufen:

App.configurePlatformSharing();
In the Windows-specific share.js, however, we do more:
WinJS.Namespace.define("App", {
  configurePlatformSharing: configurePlatformSharing,
  share: share
});
function configurePlatformSharing() {
  var dataTransferManager = 
    Windows.ApplicationModel.DataTransfer.
    DataTransferManager.getForCurrentView();
  dataTransferManager.addEventListener("datarequested", provideData);
}

Im vorangegangenen Code erstellt "provideData" das geeignete Datenpaket, dessen Ergebnis eine systemeigene "Teilen"-Charm-Erfahrung unter Windows 8.1 und Windows Phone 8.1 ist, wie in Abbildung 14 dargestellt.

Teilen unter Windows 8.1 und Windows Phone 8.1
Abbildung 14 Teilen unter Windows 8.1 und Windows Phone 8.1

Der letzte Teil unserer App besteht im Erzwingen einer reinen Hochformatansicht, was uns die Gelegenheit gibt herauszufinden, wie wir nötigenfalls die vollständige Kontrolle über plattformspezifische Manifeste mithilfe des Ordners "res/native" übernehmen können. In diesem Fall reicht es für Android aus, wenn wir "Allgemein | Ausrichtung" im "config.xml"-Editor auf "Hochformat" festlegen, was aber zum Zeitpunkt der Niederschrift dieses Artikels keine Auswirkungen auf Windows und Windows Phone hat. Kein Problem, wir können einfach einige benutzerdefinierte Einträge in den App-Manifesten vornehmen.

Hierzu führen Sie eine Builderstellung aus und wechseln zu "bld/platforms/windows", wo Sie generierte Manifeste namens "package.windows.appxmanifest" (Windows 8.1), "package.phone.appxmanifest" (Windows Phone 8.1) und "package.windows80.appxmanifest" (Windows 8) vorfinden. Kopieren Sie die jeweils benötigten Manifeste in "res/native/windows", und nehmen Sie Ihre Änderungen vor. Um die Hochformatausrichtung zu erzwingen, ist dies alles, was wir im Knoten "Anwendung | Anwendung | VisualElements" benötigen (dargestellt für Windows 8.1, verwenden Sie für Windows Phone 8.1 das Namespacepräfix "m3:" und kein Präfix für Windows 8):

<m2:InitialRotationPreference>
  <m2:Rotation Preference="portrait" />
  <m2:Rotation Preference="portraitFlipped" />
</m2:InitialRotationPreference>

Zur Buildzeit übersetzt Cordova die Startseiteneinstellung und individuelle Einstellungen in "config.xml" in das plattformspezifische Manifest, zusammen mit plattformspezifischen Details aus Plug-Ins. Insbesondere werden Sie, wenn sie sich die Datei "plugin.xml" in allen Plug-In-Ordnern ansehen, Einträge wie den folgenden sehen:

<platform name="windows">
  <config-file target="package.windows.appxmanifest"
    parent="/Package/Capabilities">
    <Capability Name="picturesLibrary" />
    <DeviceCapability Name="webcam" />
  </config-file>  <!-- ... -->
</platform>

Der voranstehende Code besagt "Füge für Windows-Ziele in der "package.windows.appxmanifest"-Datei diese Capability- und DeviceCapability-Elemente unter dem Knoten "Paket | Funktionen" hinzu". Ein Ausrichtungs-Plug-In könnte ganz offensichtlich dieselbe Aufgabe erledigen, die wir hier manuell durchgeführt haben. Und somit haben wir eine funktionsfähige App!

Debuggen, Bereitstellen und andere Aspekte des App-Lebenszyklus

Als Entwickler wissen Sie zweifellos, dass das Schreiben von Code nur ein Teil des Gesamtprozesses der Herstellung einer marktfähigen Software ist, und Visual Studio kann Ihnen hier einiges bieten, wie Sie in Abbildung 15 sehen können.

Abbildung 15 Zusätzliche Visual Studio-Funktionen für Cordova-Apps

Feature Beschreibung/Hinweise
Debuggen

Zum Zeitpunkt der Niederschrift dieses Artikels unterstützen die folgenden Geräte und Emulatoren das Debuggen in Visual Studio mit der JavaScript-Konsole und dem DOM Explorer:

  •    Android 2.3.3 und höher (4.4 oder höher ist optimal)
  •    iOS 6, 7, 8
  •    Windows 8 und 8.1
  •    Apache Ripple (Chrome-basierter Emulator) für Android und iOS

Debuggen unter Windows Phone 8 und 8.1 wird zurzeit nicht unterstützt, aber Sie können das weinre-Projekt (Web Inspector Remote) verwenden, wie in einem Microsoft Open Technologies-Blogbeitrag unter bit.ly/1y9k0zr beschrieben.

Bei der Ausführung in Ripple kann die berüchtigte Meldung "I Haz Cheeseburger?!?!" auftreten. Informationen hierzu finden Sie in den häufig gestellten Fragen (FAQ) zu Visual Studio Tools unter bit.ly/1x71P0q. Und im Zweifelsfall klicken Sie einfach auf die Schaltfläche "Success". Es gibt auch einen Hinweis in der Standarddatei "index.js", der besagt, dass die "window.location.reload"-Funktion in der JavaScript-Konsole ausgeführt werden soll, um Initialisierungscode zu debuggen. Bedenken Sie hierbei, dass hierdurch der neueste Build nur neu geladen wird – die App wird nicht neu erstellt, und es werden auch keine Änderungen auf Quelldateien angewendet.

IntelliSense Visual Studio bietet Ihnen IntelliSense für HTML-, CSS- und JavaScript-Code, einschließlich einer wachsenden Anzahl von Drittanbieterbibliotheken wie "JQuery", "Backbone.js" und "Require.js".
Testen Appium und Chutzpah sind beliebte Open Source-Automatisierungstools. Chutzpah Test Runner für Visual Studio lässt sich in den Visual Studio-Test-Explorer und in Team Foundation Build integrieren. Für breit angelegte Gerätetests können Sie Dienste wie Perfecto Mobile verwenden.
Application Lifecycle Management Visual Studio ALM-Funktionen unterstützen agile Planung, Quellcodeverwaltung (gehostet auf Team Foundation Server oder GitHub), Zusammenarbeit im Team und Releaseverwaltung für plattformübergreifende Projekte und Teammitglieder, die andere IDEs verwenden.

Wenn Sie mit dem Erstellen von Cordova-Apps anfangen, ist es hilfreich, zu wissen, dass Sie auf allen Plattformen merkwürdiges Verhalten vorfinden werden. Das liegt einfach in der derzeitigen Natur der plattformübergreifenden Entwicklung, was bedeutet, dass Sie realistischerweise mit einem so hohen Debugaufwand pro Plattform rechnen sollten, wie er anfiele, wenn Sie systemeigene Apps für jede Zielplattform schreiben. Ähnlich erfolgt die Entwicklung in jedem App Store individuell, wobei Tools verwendet werden, die für die jeweiligen Plattformen spezifisch sind. Cordova kürzt diese Prozesse nicht ab.

Die plattformspezifischen Builds binden die geeigneten Ressourcen in den Ordner "res" Ihres Projekts ein: Stellen Sie sicher, dass Sie diese Inhalte überprüfen und sich vergewissern, dass Sie über all die richtigen Grafiken und anderen Dateien für alle Plattformen verfügen. Wenn Sie Ihr endgültiges Paket zusammenstellen, überprüfen Sie noch einmal die Manifeste, um sicherzustellen, dass Ihre App und Ihr Unternehmen richtig identifiziert werden und dass Sie keine Daten aus der Standardprojektvorlage übernehmen.

Und wenn Ihre App zur Auslieferung an echte Kunden bereit ist, widmen Sie sich nachdrücklich der Behandlung von Problemen mit zeitnahen Updates der App. Selbst bei nur einer Plattform gibt es eine so große Vielfalt bei den Geräten, dass Kunden de facto Ihre Testbenutzer sein werden – würdigen Sie diese Rolle also durch schnelle Updates.

Ausblick auf Funktionen kommender Visual Studio-Versionen

Wir können abschließend sagen, dass wir bereits gesehen haben, wie die Visual Studio Tools für Apache Cordova viel zur Vereinfachung der plattformübergreifenden Cordova-Entwicklung beitragen. Microsoft Open Technologies selbst liefert bedeutende Beiträge zum Cordova-Projekt, und das Visual Studio Tools-Team engagiert sich dafür, die Erfahrung noch zu verbessern – was wir in diesem Artikel behandelt haben, ist also nur eine Vorschau! Im Verlauf der zukünftigen Entwicklung wird sich das Team mit App-Funktionen beschäftigen wie Pushbenachrichtigungen, umfassenderem IntelliSense, verbessertem Debugging auf mehr Plattformen, HTML/CSS-Designern, verbesserter Unterstützung für Komponententests, Unterstützung für Team Build und Beschleunigung und Unterstützung des Standardworkflows für Webentwickler. Gibt es weitere Funktionen, die Sie gerne hätten? Senden Sie uns Ihr Feedback über die Microsoft UserVoice-Website (visualstudio.uservoice.com) oder per Twitter unter @VSCordovaTools, und beteiligen Sie sich an der Diskussion über das Toolkit auf StackOverflow (bit.ly/1yCReYa).

Tipps, Tricks und Hinweise

Verschieben von Zielen: Um einfach zwischen Zielplattformen wechseln zu können, fügen Sie das Projektmappenplattformen-Steuerelement Ihrer Symbolleiste hinzu, wie im MSDN Library-Artikel "Create Your First Hello World App" unter bit.ly/1th836k beschrieben.

PhoneGap und Cordova: Cordova hat als mobiles Framework und Buildsystem namens PhoneGap begonnen, hergestellt von Nitobi Software Ltd., entworfen, um die Lücke zwischen unterschiedlichen Mobiltelefonplattformen durch Abstraktion von Unterschieden hinter einem Framework zu überbrücken. 2011 hat Adobe Systems Inc. Nitobi übernommen und in Folge das Framework als Apache Cordova in der Apache Software Foundation auf Open Source umgestellt, wobei Microsoft Open Technologies zu diesem Projekt bedeutende Beiträge liefert. Adobe betreibt das Cloud-basierte Buildsystem "PhoneGap", das systemeigene App-Pakete aus Webcode erstellt, sodass Sie keine systemeigenen SDKs auf Ihrem eigenen Computer benötigen.

Android-Emulatoren: In der Entwicklercommunity ist man sich nahezu einig, dass man auf die Android SDK-Rohemulatoren verzichten sollte, ähnlich wie auf Internet-Einwählverbindungen, es sei denn, man konfiguriert VM-Beschleunigung. Visual Studio 2015 Preview enthält den schnellen Hyper-V/x86-basierten Visual Studio-Emulator für Android (bit.ly/1xlRwFT), der mit dem Windows Phone-Emulator kompatibel ist (und der nach seiner Installation mit Visual Studio 2013 Update 4 funktioniert). Sie können auch den GenyMotion-Emulator für Android verwenden, wenn Sie Visual Studio 2015 Preview nicht installieren möchten.

Cordovas Komfortzone: Entwickler sind sich im Allgemeinen bewusst, dass das Ausführen von HTML, CSS und JavaScript in einer Cordova-App nicht immer eine wirklich systemeigene Erfahrung auf allen Plattformen zeitigt. Cordova-Apps eignen sich aber optimal für Erfahrungen mit hoher Markenpräsenz, die sich nicht an systemeigene Benutzeroberflächenmuster halten müssen, sowie für Unternehmens-Apps, bei denen eine Differenzierung zwischen Plattformen nicht erwünscht ist. Cordova ist außerdem ein effizientes Mittel zum schnellen Erstellen von Produktions-Apps, mit denen Ideen im Markt getestet werden, um ein besseres Verständnis dafür zu bekommen, an welcher Stelle sich nachdrücklichere geschäftliche Investitionen lohnen.

Verweisen auf Remoteskriptcode: Webanwendungen laden häufig JavaScript-Bibliotheken von Remotequellen, was sinnvoll ist, weil ein Benutzer online sein muss, um die Website überhaupt anzeigen zu können. Mobile Apps sollten jedoch auch ohne Konnektivität eine gute Erfahrung liefern, weshalb es am besten ist, Remoteskriptcode herunterzuladen und direkt in das Projekt aufzunehmen. Dies ist unter Windows 8/8.1 und Windows Phone 8.1 erforderlich, wo der Systemhost Remoteskript nicht zulässt. Das Laden einer Bibliothek, die versucht, weiteren Remoteskriptcode zu laden kann hier problematisch sein, und Sie müssen möglicherweise manuell nachbessern, damit alles funktioniert.

Jede Plattform zu ihrer Zeit: Die Verwendung eines plattformübergreifenden Tools wie Cordova bedeutet nicht, dass Sie eine App auf mehreren Plattformen gleichzeitig ausliefern müssen. Sie können auch anfangs nur eine Plattform als Ziel anvisieren, in dem Bewusstsein, dass sich Ihre Investitionen später auch auf andere Plattformen übertragen lassen. Auf diese Weise können Sie Ihre Benutzeroberfläche und das CSS plattformweise optimieren.


Kraig Brockschmidt arbeitet als leitender Entwickler von Inhalten in der Microsoft Developer Division und ist spezialisiert auf die Bereitstellung von Leitfäden für Entwickler von mobilen, mit der Cloud verbundenen Apps unter Windows, iOS und Android. Er ist der Verfasser von "Programming Windows Store Apps with HTML, CSS and JavaScript" (zwei Ausgaben) bei Microsoft Press, und er veröffentlicht weitere Einblicke unter kraigbrockschmidt.com/blog.

Mike Jones ist Programmierer und arbeitet seit 10 Jahren bei Microsoft an mobilen Anwendungen, von Compact Framework über Silverlight für Windows Phone bis hin zu Visual Studio Tools für Apache Cordova. Nach einer langen und erfreulichen Liaison mit C# und Konsorten erfreut er sich in den letzten Jahren zunehmend an JavaScript.

Unser Dank gilt den folgenden technischen Experten von Microsoft für die Durchsicht dieses Artikels: Chuck Lantz, Eric Mittelette, Parashuram Narasimhan, Ryan Salva, Amanda Silver, Cheryl Simmons und Priyank Singhal