Integration von Webinhalten in Apps
Mit Windows 10 gibt es neue, leistungsfähige und spannende Möglichkeiten exisitierenden Code von Websites und Webapps wiederzuverwenden. Dieser Artikel zeigt euch, was jetzt geht. Zunächst ein paar Worte zur Motivation: Viele App Entwickler stehen vor der Herausforderung mehrere Plattformen gleichzeitig bedienen zu wollen. Ich habe in der Vergangenheit schon den ein oder anderen Artikel zu dem Thema verfasst, weil ich dieses wirklich für zentral und wichtig halte und fest davon überzeugt bin, dass früher oder später jeder Entwickler einer Client-Applikation sich mit diesem auseinandersetzen wird.
Ein valider Ansatz ist es Anwendungen erstmal nur als Website zu veröffentlichen. Ich spreche jetzt absichtlich von Anwendungen, weil es eben um mehr als eine Web-Präsenz geht. Es geht um eine Anwendung, die Nutzer Dinge tun lässt, sie produktiver macht oder bestimmte Szenarien erst ermöglicht. Ein Beispiel wäre das Abrfagen von Aktienkursen und vielleicht der An- und Verkauf. Oder das Vorbestellen von Büchern bei einer Bibliothek. Vielleicht auch eine zugangsgeschützte Applikation, über die sich unternehmensinterne Prozesse steuern lassen etc.
Web first, native second?
Zunächst nur im Web zu veröffentlichen hat den Vorteil, dass man damit mit einem Aufwasch alle Zielplattformen erreicht. Die webbasierten Officeanwendungen beweisen z.B. eindrucksvoll, was alles schon geht. Trotzdem kann es natürlich sein, dass man – obwohl man im Web schon vertreten ist – dennoch noch auf einer oder möglichst vielen Plattformen nativ vertreten sein will. Hier geht das Theater dann los: Alles nochmal schreiben? Für alle relevanten Plattformen? Kann man nicht einen Teil der bereits im Web implementierten Fähigkeiten wiederverwenden?
Eine App um der App Willen?
Ich denke, man darf zunächst ruhig mal kurz in Frage stellen, ob jemand, der eine gut funktionierende mobile und responsiv ausgerichtete Website hat tatsächlich eine "App" benötigt. Insofern sollte in jedem Fall am Anfang aller Überlegungen die Frage stehen, was die App haben wird, was die mobile Website nicht hat. Im Idealfall fallen einem hier jede Menge Gründe ein.
Vielleicht ist ein Grund das Listing im App Store/Windows Store / Play Store. Das kann aus Marketinggesichtspunkten ein guter Grund sein und ich höre das von vielen Kunden. Oft höre ich auch Sätze wie "die Führungsriege will es so". Auch das kann ein Grund sein. Hoffentlich ist es nicht der einzige.
Im Idealfall ist der Grund, dass man eine tiefere Integration ins Betriebssystem möchte, um eine bessere Usability zu bekommen und dem Anwender einen echten Mehrwert bieten will. Vielleicht liegt auch ein Wunsch nach verbesserter Offlinefähigkeit vor, wobei hier angemerkt sei, dass auch Websites nach HTML5 offlinefähig sein können. In jedem Fall sei angemerkt: Als Anwender erwarte ich, dass eine App mehr kann als nur eine Website zu "wrappen". Womit wir bei einem anderen Thema wären:
Welche Möglichkeiten gibt es überhaupt meine Anwendung ins Betriebssystem zu integrieren?
Wer hier nach Möglichkeiten sucht, dem möchte ich als Denkanstoß nur folgendes mitgeben: Wer eine Windows Universal App schreibt, der kann sich über diverse App-To-App Communication Wege mit anderen Apps austauschen (u.a. Drag & Drop), kann seine Funktionalität als App-Service anbieten (die App wird unsichtbar im Hintergrund gestartet und tut dann was), kann bestimmte Tätigkeiten durchführen, die von anderen Anwendungen getriggert werden (beispielsweise könnte eine Shopping App den Geldtransfer durch eine Banking App anstoßen), kann auf alle Windows Universal APIs zugreifen und demzufolge auch Hardware (auch Sensoren) ansprechen und kann auch eine Integration mit Cortana für seine App ermöglichen. Denkbar wäre hier das Szenario, dass ich Cortana zurufe, dass ich für einen angegebenen Betrag an Geld Aktion eines bestimmten Unternehmens kaufen will. Daraufhin könnte die App starten, und die Transaktion starten. Vermutlich sollte die App noch eine TAN abfragen, aber das ist ein anderes Thema. All das geht mit einer normalen Webseite nicht. Natürlich geht noch viel mehr, dass sollte ja nur ein kleiner Denkanstoß sein.
Wiederverwendung von bestehendem Webcode
Gehen wir davon aus, dass wir uns ausgiebig Gedanken gemacht haben. Nehmen wir entscheiden uns tatsächlich eine App zu erstellen, die auch im Store gelistet werden soll – welche Möglichkeiten gibt es nicht bei null anfangen zu müssen?
Hosted Web Apps für Windows 10
Hosted Web Apps bieten die Möglichkeit eine Website als "App" zu verpacken und im Store zu listen. Auf den ersten Blick klingt das wie ein gezieltes Veräppeln der Anwender – wenn sich hinter der App dann ohnehin nur die Website verbirgt – wo wäre der Vorteil der App? Genau das wollen wir ja eigentlich nicht, wie oben bereits beschrieben! Zum Glück bringen die Hosted Web Apps eine weitere entscheidende Fähigkeit mit: Sie können beliebige Windows Runtime APIs aufrufen. Richtig gelesen: Es ist mögich über Hosted Web Apps, deren Javascript Code nicht teil des App Packages ist, sondern die eben "hosted" sind, also auf einem Server liegen, Windows APIs aufzurufen. Welche? Alle! Das ist spektakulär! Auf diese Weise kann man also eine servergehostete Webapplication erstellen, den Javascriptcode um Zugriffe auf Windows.XXX.YYY APIs erweitern und die Hosted Web App wird zur Laufzeit die Zugriffe zulassen. Zwei kleine Anmerkungen:
- Die Zugriffe auf die Windows Runtime APIs funktioniert nur, wenn die App im Rahmen der Hosted Web App im App Context ausgeführt wird, wenn man die App im Browser aufruft, wird der Zugriff nicht zugelassen.
- Um die gehostete Website auch weiterhin im Browser ausführen zu können, ist es natürlich empfehlenswert an dieser Stelle mit Feature Detection im Browser zur Laufzeit abzufragen, ob die APIs vorhanden sind. Aber das ist für Webentwicklung heutzutage ohnehin Best Practice.
Als App Entwickler kann ich im App-Manifest definieren, welche Domain Zugriff auf die APIs haben soll. Damit kann man sprichwörtlich mit 4 Zeilen Code eine App erstellen, die funktionert.
Im Manifest legt man fest, von welcher Seite aus Zugriffe auf Windows APIs im Rahmen der App zugelassen werden:
<uap:ApplicationContentUriRules>
<uap:Rule Type="include" WindowsRuntimeAccess="all" Match="https://meinewebapplication.example.com/" />
</uap:ApplicationContentUriRules>
Außerdem legt man die "Startseite" der Applikation fest. Das kann eine beliebige Seite auf obiger Domain sein.
StartPage="https://meinewebapplication.example.com/index.html"
Bitte nochmal den folgenden Hinweis ernst nehmen: Meine Empfehlung ist es eine Hosted Web App tatsächlich mit Mehrwert zu versehen, also den Zugriff auf APIs dann auch zu nutzen. Eine einfach gewrappte Website führt zumindest in meinem Fall eher zu Frustration beim Anwender.
Native (packaged) HTML5/JS App
Das andere Extrem ist natürlich das Verpacken und Ausliefern des kompletten HTML/JS Codes innerhalb einer Anwendung. Bereits mit Windows 8 haben wir ja die Möglichkeit eingeführt komplette Clientanwendungen auf Basis von HTML5 zu schreiben. Da immer wieder Fragen aufkommen, ob diese mehr oder weniger können, als Apps auf Basis von C#/XAML: Nein – unten drunter liegt die Windows Runtime, die in beiden Fällen die exakt gleichen APIs liefern. Es ist also in beiden Fällen das gleiche möglich. Man kann auch beliebige JS-Frameworks einsetzen, typischerweise arbeitet man mit der WinJS Library.
Wer eine Single Page Application ohne serverseitige Codeerzeugungsframeworks wie ASP.NET oder PHP hat und hier die komplette Navigation und Logik über HTML5 & JS abwickelt, der kann tatsächlich den vorhandenen Websitecode einfach in die Windows Universal App kopieren – und die App sollte ohne große Überraschungen laufen.
Wenn das nicht der Fall ist, so sind in der Regel zumindest die Logikkomponenten in Javascript schmerzfrei importierbar. Diese Art von App bringt alles mit, was sie anzeigt – es ist eben eine ganz normale App. Zugriff auf lokale APIs ist natürlich möglich, wie gesagt: Es ist eine ganz normale App.
Integration via Webview
Nun haben wir beide Extreme kennengelernt. Die gute Nachricht ist, dass man jetzt auch dazu übergehen kann beide Varianten zu mischen: Das heißt, ich kann eine native App mit lokalem Content schreiben (egal in welcher Sprache, bleiben wir mal bei HTML5/JS) und kann darin eine sogenannte WebView integrieren, die serverseitig gehosteten Content aufruft.
Eine Webview ist ein Controll, das für XAML und HTML exisitiert. Man kann sich das vorstellen wie eine Art Iframe, den man in einer Website einbedded, nur: Es ist eben kein Iframe. Man könnte tatsächlich auch einen Iframe verwenden, der aber gewisse Nachteile mit sich bringt, da man als Entwickler zum Beispiel nur eingeschränkten Zugriff auf die Events im Iframe hat und nie so richtig weiß, was eigentlich schon geladen ist, was nicht etc.
Aus diesem Grund haben wir mit Windows 8 das WebView Control eingeführt, was jetzt in der neuesten Version vorliegt und zusätzliche Funktionen mitbringt. Das WebView unterstüzt von Haus aus die Pinch-Geste zum Zoomen von Inhalt, unterstützt die SmartScreen Technologie um Inhalte auf Gefährdung zu überprüfen und bietet einen Möglichkeit Screenshots des Inhalts zu machen. In Windows 10 wird es noch um neue Events erweitert, die Entwicklern erlauben beispielsweise das Abfragen von Permissions ("Darf diese Website auf die Geoposition zugreifen?") programmatisch zu beantworten. Solche Abfragen werden also gar nicht an der Nutzer weitergeleitet. Das ist auch ok, wir befinden uns ja im App-Context, hier hat der Programmierer ohnehin die Kontrolle.
Darüberhinaus läuft das WebView nicht mehr im UI Thread und blockt so nicht die komplette App, wenn die Website hakt. Inhalt, der nicht im Browser dargestellt werden kann (zum Beispiel eine .Zip-Datei) wird als "unviewable content" erkannt und kann durch den Entwickler speziell behandelt werden. Hier ist es auch möglich, den Content dynamisch auszuwerten und dann eine entsprchende darstellbare Ansicht anzuzeigen.
Kommunikation mit dem WebView Control kann aus dem WebView Control heraus über ScriptNotify() erfolgen. So kann der Webcode den Appcode ansprechen, vorausgesetzt der Appcode lauscht auf das entsprechende Event. Umgekehrt kann über InvokeScript die App Webcode aktivieren.
Es ist also bidirektionale Kommunikation möglich – leider mutet das aber etwas hakelig an. Aus diesem Grund wurde mit dem neuesen WebView Control die "AddWebAllowedObject" Api eingeführt, die es möglich macht ein Objekt aus der App innerhalb des WebViews zur Verfügung zu stellen. In Konsequenz ist so eine einfachere Kommunikation mit aus dem Webview heraus möglich.
Cordova
Neben dem wirklich mächtigen WebView sei der Vollständigkeit halber noch Cordova genannt. Visual Studio 2015 bringt die Cordova Tools von Haus aus mit und das Cordova Framework erlaubt es auf Basis von HTML und Javascript für eine ganze Palette von Devices zu entwickeln – mit einer einzigen Codebasis. Die APIs werden dabei von Cordova gekapselt. Das ist nicht neu, wird aber erstmals standardmäßig mit Visual Studio ausgeliefert. Good News: Auch im Falle von Cordova kann ich jetzt gehosteten HTML/JS Code nutzen.
Fazit
Unterm Strich kann hat man als Webentwickler jetzt eine sehr breite Möglichkeit zum einen die eigenen Fähigkeiten, zum anderen aber auch die eigenen Assets in Form einer App auf die Windows Plattform zu bringen. Ausgehend von Windows 8.1 wurden hier noch einmal riesige neue Optionen geschaffen. Die Möglichkeit aus Javascriptcode, der auf dem Webserver gehostet ist, heraus Windows APIs zu adressieren, ist dabei für mich persönlich der absolute Hammer. So wird es wirklich zu einer leichten Übung WebSites tiefe Integration in das Betriebssystem aufzuwerten.