+49 40 608 12 460 (Development)
+49 175 5611694 (Kommunikation)

Titanium versus PhoneGap (HTML5)

Wir entwickeln seit 2009 mobile Apps für den Enterprisebereich und haben uns für das CrossPlatform-System Appcelerator Titanium entschieden. In vielen Gesprächen mit Entwicklern und auf Konferenzen werden wir oft gefragt, wie sich das System vom Alternativprodukt PhoneGap (HTML5) unterscheidet.

Von weitem betrachtet scheinen PhoneGap und Titanium sich zu ähneln. So sind beide Systeme plattformübergreifende Open Source Entwicklungssysteme, die JavaScript verwenden: Das Titanium Mobile SDK wird unter der Apache 2.0 Lizenz veröffentlicht – PhoneGap, kann man als Distribution des von der Apache Software Foundation betreuten Projektes „Cordova“ ansehen.

Um beide Technologien abzugrenzen, werden wir die beiden architektonischen Unterschiede aufzeigen, Stärken und Schwächen benennen und dann abschließend versuchen ein Fazit zu geben.

Beginnen wir mit der Erkundung von PhoneGap und wie es funktioniert.

PhoneGaps Architektur

Das Grundprinzip von PhoneGap besteht darin, in einem nativen Webcontainer HTML-basierte Web-Anwendungen einzubauen. Da sie in diesem Container verpackt sind, können sie  in öffentlichen AppStores vertrieben und installiert werden. Es entstehen also tatsächlich Binärpakete für alle führenden Plattformen.
Darüberhinaus bemüht sich PhoneGap, mit einem native API-Set in der Regel nicht verfügbare Brücken zu Geräteschnittstellen zu schaffen. Damit kann diese Miniwebseite beispielsweise auf die Kamera oder andere Hardwarefunktionen zugreifen.
In diesem Sinne ist PhoneGap als Vorhut der neuen W3C Device-API-Standards zu sehen. Mozilla und Microsoft machen gerade einen vielversprechenden Anlauf in diese Richtung.

Arbeitsablauf für den Entwickler

Um PhoneGap-Anwendungen zu entwickeln, werden die Entwickler in einem lokalen Verzeichnis  die nötigen HTML-, CSS- und JavaScript-Dateien erstellen. Das passiert ähnlich wie bei der Entwicklung einer statischen Website. Diese gleiche Arbeitsumgebung wird von vielen Webentwicklerns als Vorteil angesehen.
Damit die WebApp in einem nativen Emulator/Simulator laufen kann, muss der Entwickler für jede Plattform das jeweilige SDK installieren. Das HTML-Verzeichnis ist dann Bestandteil dieses Projektes, beispielsweise in einem Verzeichnis 'www' im Resourcenverzeichnis. Eventuell erleichtern symbolische Links die Entwicklung für mehrere Plattformen.

Um die „native“ App auf dem Zielgerät laufen zu lassen, benötigt es ähnliche Schritte. In der iOS-Welt wird ein entsprechendes Entwickerzertifikat benötigt. Auf Androidgeräten muss der Entwicklermodus eingeschaltet sein und/oder der Start von unbekannten Apps erlaubt sein. Die App kann dann auf üblichen Wegen (USB oder Web) installiert werden.


Da der Setup alle SDKs nicht jedermanns Sache ist und nicht jeder Entwickler ein Gerät von Apple sein eigen nennt, hat Nitobi (kürzlich von Adobe aufgekauft) einen Clouddienst eingerichtet. Der Entwickler kann nun sein HTML-Verzeichnis gezippt hochladen oder die URL-Adresse im Github bekanntgeben. In beiden Fällen findet der Build-Prozess in einer Cloud statt. Ergebnis sind die jeweiligen Binaries der Plattformen. Es werden auch QR-Codes angeboten. So kann direkt auf dem Zielgerät (onAir) installiert werden. Das setzt natürlich die Konfiguration der Provisioningdateien bzw. Zertifikate voraus. Dieser Clouddenst unterstützt allerdings nur ein Subset der PhoneGap-Module. So werden SQLite – und erst recht eigene Module –  nicht unterstützt. Dieser Dienst ist also eine Hilfe für sehr einfache Projekte.

Für die eigentliche Entwicklung können Standard-Werkzeuge wie Firebug, Webinspector  und ein Texteditor/IDE der Wahl eingesetzt werden. Es gibt auch ein neues  Werkzeug für Remote-Debugging. Es nennt sich Weinre und ermöglicht ähnliche Debuggingmöglichkeiten wie beispielsweise Firebug.

Arbeitsweise von PhoneGap

Wie bereits erwähnt, ist ein PhoneGap-Anwendung ein „native-wrapped“- HTML5-Anwendung.

Viele native, mobile Entwicklung-SDKs bieten einen Web-Browser-Widget  als Teil ihres UI-Frameworks an. Sinn dieser View besteht in rein nativen Anwendungen darin,  HTML5-Inhalte in der nativen UI anzuzeigen. Die Webinhalte können dabei lokal sein (also mit einkompiliert sein) oder zur Laufzeit aus dem Netz „gezogen“ werden. Die native Wrapper-Anwendung von PhoneGap generiert genau eine solche Webansicht, in der dann das vom Entwickler gebaute HTML  angezeigt wird.

Geladenes JavaScript wird in ihrem Seitenkontext ausgewertet. Zusätzlich kann der native Container (ObjectivC/Java) asynchron mit dem in der  Webseite  laufenden JavaScript kommunizieren.

Wie wir später sehen werden, bedeutet diese „Brücke“  trotz ihrer Namensgleichheit etwas etwas völlig anders als in Titanium.

PhoneGap nutzt diese Brücke, um mit seiner JavaScript-API zwischen dem Javascriptnamensraum der Webseite und der nativen Welt Informationen auszutauschen.

Die Art und Weise wie die Brücken implementiert ist, hängt von der Plattform ab. Wenn beispielsweise in iOS auf die Kontaktliste zugegriffen werden soll, dann kommt der Aufruf Richtung iOS in eine Warteschlange. PhoneGap erstellt dann einen IFRAME mit dem URI-Schema (gap://).  Die native ContainerApp ist so konfiguriert, dass sie diese Befehle entgegennimmt und ausführt. In umgekehrter Richtung läuft die Kommunikation dementsprechend.

Es gibt viel mehr zu PhoneGap zu sagen, aber diese Brücken-Kommunikation zwischen Webansicht  und nativem Umfeld   ist der Schlüssel, wie lokale Webanwendungen systemeigenen Code aufrufen können.

Erweiterung von Phonegap

Möchte der PhoneGap-Entwickler weitere native Funktionen nutzen, die nicht Bestandteil des PhoneGap_paketes sind, muss er eine Extension bauen. Dazu bedarf es folgender Teile:

  1. Javascript-Code, der mittels PhoneGap's API seine „Botschaft“ in die Warteschlange schreibt, die dann der nativen Welt gesendet wird,
  2. Registrierung der Extension in der nativen Welt. In iOS ist das die Cordova.plist Datei,
  3. nativer Code (ObjectivC, Java …) der auf der nativen Seite mit der Brücke kommuniziert.

Grundsätzlich können Entwickler das gleiche  asynchronen Messaging-System, das auch der PhoneGap-Kernel nutzt, verwenden.

Stärken des PhoneGap-Ansatzes

Nach unserer Einschätzung schöpft PhoneGap primäre seinen Vorteil aus der Tatsache, das es so klein und einfach ist. Es tut, was es tut, und das tut es gut. Das PhoneGap-Team hat absichtlich nur den kleinsten gemeinsamen Nenner der nativen APIs für die webbrowserbasierten Anwendung implementiert. Da das native API-Set so schmal ist, war es relativ einfach, PhoneGap zu vielen verschiedenen Umgebungen zu portieren. Grundsätzlich kann jede nativen Plattform, die eine Webansicht oder Webruntime unterstützt, eine PhoneGap-Plattform sein.

Nichtvisuelle nativen Erweiterungen  sind in PhoneGap ebenfalls sehr einfach. Einfache nativen Erweiterungen können schnell entwickelt werden. Diese Plug-in-Architektur ist unserer Meinung nach gut ausgeführt.

Ein weiterer Vorteil sehen wir darin, dass nativen APIs und native App-Entwicklung für Entwickler gut abstrahiert sind . Wer HTML, CSS und sogar ein kleines wenig JavaScript schreiben kann, der  kann eine Web-Seite in eine nativen App einpacken und so vertreiben. Einstiegsbarrieren für Webentwickler in die native Welt sind also  extrem niedrig.

Schwächen von PhoneGap

Die Qualität der Benutzerschnittstelle in einer PhoneGap-Anwendung hängt von der Qualität der Webansicht und der Renderingengine für die Plattform ab. Gewöhnlicherweise wird ein HTML5-Framework verwendet. Diese Frameworks ajaxionieren interne Links, wrappen und virtualisieren die Events und gestalten das UI. Letztlich gibt es mittlerweile für jedes JS-Framework auch eine mobile Variante. Am bekanntesten sind dabei jQueryMobile und SenchaTouch. Letzteres modifiziert nicht ein vorhandenes DOM, sondern generiert syntetisch aus Javascript das mobile DOM. Die webkitbasierte Renderingengine auf iOS ist leistungsfähig und bietet zur Zeit die beste Leistung. Die Android-Webansicht funktioniert, hat aber einige bemerkenswerte Einschränkungen.

Jeder Webentwickler kennt das Cross-Browser-Problem. In der Desktopwelt mag sich das in den letzten Jahren beruhigt haben, aber in der mobilen Welt muss man noch die ganze Trickiste von Weichen und Medienabfragen bemühen. Auch innerhalb der Webkitfamilie gibt es noch Unterschiede in entscheidenden Feinheiten.

Mobile Browser werden in letzter Zeit immer besser, was zu einer gewissen Verbesserung der Situation führt. Aber auch die Annäherung an die nativen UI-Qualität im Browser ist eine nichttriviale Aufgabe.  Sencha beschäftigt zur Lösung dieses Problems in Vollzeit ein großes Team von Web-Programmierern. Derzeit lässt sich auf den meisten Plattformen eine nativen UI-Qualität – das betrifft Leistung und Reaktionsfähigkeit –  einfach nicht realisieren.  Das klappt auch  mit dem recht fortschrittlichen SenchaTouch nicht – von jQueryMobile ganz zu schweigen.

Was heisst gut genug? Das hängt natürlich von Bedürfnissen und Befindlichkeiten ab. Aber zweifellos ist eine Webqualität immer noch deutlich anders als eine native UI. Die Qualität hängt vom Gerät, dem Betriebsystem und auch von der Softwarearchitektur der Anwendung ab.

PhoneGap kann nicht mit nativer Benutzeroberfläche erweitert werden. Der Entwickler lebt in seiner Webwelt und die Benutzeroberfläche wird in HTML gerendert. Man kann in systemeigenen Code Botschaft und damit natives UI erstellen, aber diese nativen Views sind dann immer über- oder unterhalb der Webview. Eine direkte gelayerte View über der Webview ist nicht möglich
Appcelerator ist vor Jahren mit dieser Technik gestartet und hat aber schnell festgestellt, dass diese Bemühung  suboptimale  Ergebnisse erzeugt haben oder das Ergebnis nicht vorraussehbar war.

Das Schwert des „kleinsten gemeinsamen Nenners“ hat auch eine andere Schneide. Fehlende native Funktionen werden durch  eine Vielzahl von Plugins realisiert. Nach unserer persönlichen Erfahrung gibt es dabei verschiedene Qualität und Nachhaltigkeit. Das kann sich alles verbessern. Immerhin gibt es eine grosse Community von Anwendern.

Was versucht Titanium zu erreichen?

Das Ziel von Titanium ist eine auf Javascript basierende Crossplattform-Runtime. Heute wird iOS, Android und Blackberry10 unterstützt – Windows Phone kommt bald. Titanium hat eigentlich mehr Gemeinsamkeiten mit MacRuby/Hot Cocoa , PHP oder node.js als es mit PhoneGap, Adobe AIR, Unity3D, Corona oder Rhomobile. Titanium setzt auf  zwei Grundannahmen der mobilen Entwicklung:

(1)  Es gibt einen Kern der API, die plattformübergreifend normalisiert werden kann. Diese Bereiche sollten für die Wiederverwendung von Code ausgerichtet sein.
(2)  Es gibt plattformspezifischen APIs, UI Konventionen und Funktionen, die Entwickler für die  Entwicklung für diese Plattform verwenden sollte. Plattformspezifischen Code sollte für diese Anwendungsfälle existieren, um die bestmögliche Nutzererfahrung zu bieten.

Aus diesen Gründen erhebt Titanium nicht den Anspruch der Universalität auf allen Plattformen. Vielmehr verfolgt Titanium immer das Ziel, die Vorteile der entsprechenden Plattform auszunutzen und immer im „Look&Feel“ der Umgebung daherzukommen. Es geht also um Eleganz der Bedienung  und um Vertrautheit. Aber, um es zu verdeutlichen: es ist nicht notwendig, für einen Netzzugriff oder das Zeichnen eines roten Rechteckes plattformspezifische APIs zu nutzen.

Titanium ist ein Versuch, die Wiederverwendung von Code mit einem einheitlichen JavaScript-API zu erreichen. Mit plattformspezifischen Funktionen und native Performance wird die Erwartungshaltung des Benutzer befriedigt. Wer eine Titanium-Anwendung schreibt, programmiert eine native Anwendung in JavaScript.

Arbeitsumgebung für Titanium

Grundvoraussetzung für die Titaniumentwicklung ist die lokale Installation der entsprechenden SDKs. Für iOS ist das XCode, für Android die Android-SDK. Nachdem dieses Setup erledigt ist, kommuniziert der Entwickler mit den nativen SDKs lediglich über das eclipsebasierte Titanium-Studio. Intern läuft die Kommunikation zwischen der IDE und den SDKs über Python. Für seltene Fälle kann dann auf ein CLI zurückgegriffen werden.

Mit dem Titanium-Studio generiert der Entwickler die Logik in Javascript, füllt andere Verzeichnisse mit Assets und konfiguriert seine App in XML-Dateinen. Falls tatsächlich einmal ein hybride App baut, dann können die HTML/CSS/JS-Dateien ebenfalls in diesen Ordnern abgelegt werden. Mit wenigen Zeilen Javascript liese sich auch theoretisch ein Webcontainer wie in PhoneGap bauen:

(function() {
   var win = Ti.UI.createWindow();
   win.add(Ti.UI.createWebView({
      url:'http://spiegel.de'
   }));
   win.open();
})();

Vom Studio aus können auch die  nativen Simulatoren/Emulatoren getestet und es kann gedebuggt werden. Selbstverständlich gibt es auch eine in solchen IDEs übliche Code-Vervollständigung und -validierung.

Die Aufspielung auf die Geräte als auch die Auslieferung in die öffentliche  Stores erfolgt ebenfalls aus dem Studio heraus.

Wie Titanium arbeitet

Eine mobile Anwendung ist recht komplex. Das ist dem Multitaskingnetriebsystems des Gerätes, dem Lebenszyklus von Anwendungen  und dem Diktat der Knappheit von Speicher, Batterie und Rechenleistung geschuldet. Diese Komplexität wird zur Laufzeit mit drei Hauptkomponenten abgedeckt:
- dem JavaScript-Quellcode, der in eine Java-oder Objective-C-Datei kompiliert und als kodierte Zeichenkette im System abgelegt ist,
- der plattformspezifische Implementierung der Titanium API in der nativen Programmiersprache und
- einem JavaScript-Interpreter, der zur Laufzeit den Code auswertet.

Für letzteren Interpreter wird auf Android-Maschinen V8 und auf den Apple-Geräten derJavaScriptCore genutzt. Falls tatsächlich für Teilbereiche ein Webview eingesetzt wird, dann läuft in diesem Namensraum die eingebaute JavaScript-Engine des Browsers.

Wenn die Anwendung gestartet wird, dann wird ein JavaScriptumgebung zur Ausführung im nativen Code erstellt und der Code ausgewertet. Für jedes Object in der nativen Welt gibt es ein Pendant in der Javascriptwelt.  Ein Proxy vermittelt zwischen den Objekten, ihren Methoden, Properties und den Events. Dieses Proxy wird intern Kroll-Bridge genannt.

Wird im JavaScript-Code eine Funktion aufgerufen, beispielsweise var b=Ti.UI.createButton ( {title : ' Klick mich! });, dann wird eine native Methode am nativen UI-Objekt aufgerufen und ein Proxy wird generiert. Methoden, Properties und Events sind dann in beiden Welten sichtbar.

Solche UI-Komponenten können hierarchisch angeordnet werden, um komplexere Benutzeroberflächen zu erstellen. Proxyobjekte, die eine Schnittstelle zu nichtvisuelle APIs (wie Dateisystem I/O oder Zugriff auf die Datenbank ) darstellen, werden synchron (oder asynchron für APIs wie Netzzugang ) abgearbeitet und kommunizieren beispielsweise über Events oder über Callbacks.

Um das noch einmal zu verdeutlichen: es werden keine Webkomponenten zur Gestaltung der UI eingesetzt.

Erweiterung von Titanium mit Modulen

Titanium ist um visuelle und nicht-visuelle Fähigkeiten erweiterbar. Durch die Implementierung eines Proxy und/oder einer View-Proxy-Schnittstelle in nativem Code (ObjectivC/Java) können Entwickler neue native Funktionalität für Anwendungen in JavaScript bauen. Dabei wird die gleiche Schnittstelle genutzt, die auch Titanium selber intern nutzt.

Stärken von Titanium

Das Ziel von Titanium ist eine anwendungsorientierte API für native, mobile und plattformübergreifend Entwicklung. Dabei gibt es aus der Box Zugang zu einer breiten Palette von nativen Features und Funktionen. Das betrifft alle  Komponenten der Benutzeroberfläche als auch Schnittstellen zum System. Titanium unternimmt den Versuch,  Unterschiede der Funktionalität zwischen Titanium und reinen nativen Apps  gegen Null zu reduzieren. Das wird nicht hundertprozentig gehen, aber  90% der häufigsten Anwendungsfälle werden abgedeckt und die restlichen 10% können durch Entwickler mittels Modulentwicklung ergänzt werden.

Das Aussehen der UI und die Nutzererfahrung ist nativ.  Im Unterschied zu anderen Crossplattformsystemen wird keine  visuelle Emulation mitttels HTML/CSS oder ein Rendering von UI-Widgets mit OpenGL genutzt, sondern es werden zur Laufzeit entsprechende native Elemente des Hostsystems aufgerufen. Wenn beispielsweise eine NavigationGroup erstellen wird, dann wird ein tatsächlicher UINavigationController auf iOS unterstützt. Die Animationen und Verhalten entspricht einer  nativen App, weil es die gleichen nativen Widgets ist.
Titanium bietet ein hohes Maß nativer API-Programmierung in JavaScript. Dadurch wird die Eintrittsbarriere für native Programmierung deutlich gesenkt.

Schwächen des Titanium-Ansatzes

Der Umfang der Titanium-API macht das Hinzufügen von neuen Plattformen schwierig.  Die Umsetzung der Titanium-API auf eine neue native Plattform ist ein gewaltiges Unterfangen . Aus diesem Grund wird zur Zeit nur iOS und Android unterstützt. Es gibt auch Ausgänge für HTML5, Blackberry und Tizen. Diese Plattformen haben noch nicht GA-Qualität und werden ständig verbessert.

Wegen des hohen Abstraktionsgrades sind noch nicht alle GUI-Komponenten optimal. So sind TableViews mit einer sehr hohen Anzahl von selbstgerenderten Subelementen nicht nicht wirklich „nativfühlbar“. Das neue GUI-Element ListView nutzt MVC-Konzepte und kann auch mit sehr großen Daten arbeiten.

Zusammenfassung

PhoneGap kapselt HTML5-Technik in einer nativen Hülle und erbt dadurch die Problem der Webwelt. Das sind die mangelnde Performance und Layoutsicherheit. PhoneGap verbraucht wesentlich mehr Batterieleistung und Netzwerktraffic, weil smartere Architekturkonzepte schwieriger zu realisieren sind. PhoneGap-Apps sehen auf allen Geräten gleich aus. Das kann durchaus gewollt sein – entspricht aber nicht der Nutzererwartung. Mit PhoneGap lassen sich schnell kleine Apps bauen, die allerdings häufig dann doch nur kleine Webseiten sind und eben nicht die Stärken der mobilen Geräten ausnutzen. Letztere Eigenschaft kann auch zur Ablehnung seitens Apple führen. 

Titanium nutzt keine HTML5-Technik, sondern verwendet durchgängig native GUI-Elemente. Titanium-Apps sehen wie native Apps aus und fühlen sich auch so an. Durch den uneingeschränkten Vollzugriff auf Dateisystem, SQLite und Schlüsselbund lassen sich sichere, hocheffiziente Cachingsysteme aufbauen, die schonend mit Netzresourcen umgehen. Moderne Prinzipien wie „offline first“ sind damit problemlos möglich.

Nach unseren Erfahrungen benötigen Titaniumentwicklungen weniger Entwicklungszeit als HTML5-Anwendungen, es treten weniger Unklarheiten auf und der Kommunikationsbedarf mit dem Kunden ist entspannter, da es keine Layouteinschränkungen gibt.

Bislang funktioniert Titanium über die Kroll-Bridge. Das heisst zur Laufzeit wird JS-Code interpretiert um danach im nativen Namensraum Objekte zu bilden. Über Referenzen kann dann JS auf die Properties, Methoden und Events zugreifen. In Ti.Next wird die Hyperloop-Technik genutzt. Das führt zu einer immensen Performancesteigerung. Auch können native Libs direkt eingelinkt werden.

 

Grundlage dieses Artikels ist ein Blogbeitrag von Kevin Whinnery.

Wir verweisen auch auf den Magic Quadrant for Mobile Application Development Platforms  der Gartner-Gruppe. In dieser Studio ist Appcelerator Titanium als das System mit der höchsten „Completeness of vision“ bewertet worden.