Ionic und Capacitor – die Zukunft der hybriden App-Entwicklung


Im Mai dieses Jahres gab das Ionic Framework Team die Veröffentlichung des Open-Source-Projektes Capacitor bekannt und leitete damit eine kleine Revolution in der hybriden App-Entwicklung ein. Capacitor ist ein nativer Container, mit dem webbasierte Apps auf Android, iOS, Deskop und im Browser ausgeführt werden können.

Ionic-Agentur, Ionic und Capacitor
Ionic-Agentur

Jeweils mit vollem Zugriff auf die jeweiligen nativen Schnittstellen und Möglichkeiten. Capacitor ist vergleichbar mit Cordova/Phonegap, nur um ein Vielfaches besser. Capacitor ist Cordova in modern. Das Ionic Team hat echte Arbeit geleistet, um den hybriden Entwicklungsprozess zu vereinfachen und zu optimieren.

Capacitor kann als eigenständiges Tool genutzt werden, um beliebige Web-Apps für die jeweiligen Plattformen bereitzustellen. Capacitor ist aber auch direkt in Ionic integriert. In Zukunft hat man also die Wahl zwischen Ionic/Cordova oder Ionic/Capacitor, wobei die Weichen klar auf Capacitor gestellt sind!

Die Probleme von Cordova

Welcher Ionic-Entwickler kennt nicht die alltäglichen Probleme bei der Erstelung hybrider Apps mit Cordova. Cordova ist ein gewachenses System zur Erstellung eines nativen Containers für webbasierte Apps, das einige strukturelle Mängel und Probleme aufweist. Und uns Entwickler manchmal an den Rande der Verzweiflung treiben kann. Sämtlicher Zugriff auf native Funktionen, wie Kamera, Bluetooth, Push-Notications oder allgemeine App-/Geräteinformationen müssen über einzelne, meist über Drittanbieter/Community entwickelte Plugins hinzugefügt werden. Plugins die gegenseitig Probleme bereiten können, bleiben dabei nicht aus.

Für Ionic Apps muss neben dem grundlegenden Cordova-Paket auch die jeweilige Plattform (iOS/Android) als Paket hinzugefügt werden. Das bedeutet sehr viele (Paket-)Abhängigkeiten, unterschiedliche Versionen und damit verbundene Versionskonflikte. Dazu kommen noch die Abhängigkeiten zu Node.js und der jeweilig nativen Toolkette (Xcode mit Command Line Tools, Android Studio, Android SDK,…). Die Kompilierung, das Starten der App auf Emulatoren und Endgeräten muss über die Cordova CLI ausgeführt werden, wobei es bei Inkompatibilität der unterschiedlichen Systeme und Pakete immer mal wieder zu zeitraubenden Problemen kommen kann.

Die Konfiguration der einzenen Plattformen (Berechtigungen, Ressourcen, Umgebungsvariablen, Entitlements,…) müssen über eine Cordova-spezifische Konfigurationsdatei (config.xml) definiert werden. Auch hier kann es immer wieder zu Problemen und Überschneidungen kommen. Und wer schon einmal versucht hat, ein externes natives Framework (wie zum Beispiel OpenCV) als Cordova-Plugin einzubinden, weiß welche Höllentäler ein Entwickler manchmal durchschreiten muss. Inbesondere der Zugriff auf individuelle, native Funktionalitäten ist über Cordova ein Graus.

Aber wir möchten uns nicht nur beschweren: Cordova hat uns und vielen Entwicklern über Jahre und vermutlich auch noch weiter einen guten Dienst geleistet. Doch nun geht es halt besser und einfacher.

Der „Capacitor Way of Development“

Das Ionic Team hat sich diesen Problemen angenommen und mit Capacitor einen ganz neuen Weg der hybriden App-Entwicklung eingeschlagen. Capacitor stellt zu einem Web-Projekt einen nativen Container mit allen grundlegenden API-Zugriffen bereit. Beide Welten, natives Rahmenprojekt und webbasierter Kern, existieren dabei gleichberechtigt nebeneinander. Alle nativen Konfigurationen, Einstellungen und Erweiterungen können/müssen direkt in Xcode oder Android Studio vorgenommen werden.

Das Kompilieren, Installieren und Testen auf Emulatoren/Endgeräten erfolgt dabei direkt in den nativen Entwiclungsumgebungen. Damit müssen sich hybride App-Entwickler zwar etwas detaillierter mit Xcode und Android Studio beschäftigten, die deutliche Vereinfachung der gesamten Toolkette dürfte aber diesen kleinen Nachteil bei Weitem aufwiegen.

Aber schauen wir uns an, wie die Vorgehensweise einer Ionic-Entwicklung über Capacitor aussieht…

Erste Schritte mit Ionic und Capacitor

Capacitor erstmalig einrichten

Starten wir ein kleines Projekt von Grund auf und schauen uns die benötigten Befehle beim Einrichten eines Ionic-Capacitor-Projektes an:

ionic start myTestApp
ionic integrations enable capacitor
npx cap init myTestapp my.test.app
ionic build
npx capp add ios
Zuerst einmal erstellen wir wie gewohnt eine neue Ionic-App (1) und aktivieren im Anschluss die Capacitor-Unterstützung (2). Danach initialisieren wir die Capacitor-Konfiguration (3) über den App-Namen und die Package-Id der App. Mehr muss in Capacitor nicht konfiguriert werden, alle restlichen Konfigurationen erfolgen direkt in Xcode oder Android Studio.

Bevor wir eine Plattform hinzufügen müssen wir das Projekt einmalig erstellen/kompilieren (4), danach können wir beispielsweise ios (oder android) als Plattform (5) hinzugefügen.

Capacitor erstellt dabei im Root-Verzeichnis des Projektes einen Ordner ios (oder android) und darin ein eigenständiges Xcode-Projekt, das eine Kopie der webbasierten App enthält. Anders als in Cordova, muss der native Ordner ios/android auch mit in die Versionsverwaltung übernommen werden, da wie bereits erwähnt alle native Konfigurationen und Erweiterungen direkt dort vorgenommen werden.

Änderungen in der Webapp übernehmen

Ändert sich etwas im webbasierten App-Code, muss dieser neu erstellt und in das native Projekt synchronisiert werden:

ionic build
npx cap copy

Native Entwicklungsumgebung öffnen

Das Projekt kann dann direkt in Xcode (oder Android Studio) manuell geöffnet und auf Emulatoren/Endgeräten ausgeführt werden. Alternativ kann das Xcode-Projekt über die Kommandozeile geöffnet werden:

npx cap open ios

Danach kann das Projekt ganz normal in Xcode kompiliert und auf Emulatoren/Endgeräten getestet werden.

Und was ist mit Live-Reload?

Das manuelle Kompilieren der Web-Anwendung und die Synchronisierung erscheint im Gegensatz zu Cordova als etwas aufwändiger. Der Schritt wird aber eigentlich kaum, bzw. nur in der Endphase beim endgültigen Deployment benötigt. Während der Entwicklung kann zeitsparend wie in Cordova gewohnt per Live-Reload entwickelt werden.

Und dank der Vereinfachung der Toolkette auch deutlich weniger fehler- und problemanfällig. Dazu muss einfach über die Kommandozeile der Live-Reload-Server gestartet werden:

ionic capacitor run ios -l --address=0.0.0.0
Markup

Danach kann das Projekt direkt in Xcode auf Emulatoren/Endgeräten gestartet werden, die Live-Reload-Funktion ist automatisch aktiv. Ein schnelles Wechsel zwischen Emulatoren über Xcode inklusive.

Es müssen weder Target-Namen oder -Ids von den unterschiedlichen Emulatoren über die Kommandozeile ermittelt werden. Noch muss zwischen dem Native-Run-Modul von Ionic und Cordova (Stichwort –no-native-run) gewechselt werden, weil einer der beiden Möglichkeiten wieder mal inkompatibel mit den installierten Paketen, bzw. der Systemumgebung ist.

Ein Klick auf den Play-Button in Xcode reicht. Jawohl, hybride Entwicklung kann auch Spaß machen!

Zugriff auf native Funktionen und Erweiterungen

Nativer Zugriff „Out Of The Box“

Capacitor beinhaltet alle grundlegenden Schnittstellen zu den nativen Funktionen, seperate Plugins wie bei Cordova werden nicht benötigt. Folgende Grundfunktionalitäten können in Capacitor unter anderem direkt genutzt werden:

  • App
  • Background-Tasks
  • Camera
  • Device
  • Local Notifications
  • Modal
  • Motion
  • Network
  • Push Notifications
  • Storage

Beispiel: Zugriff auf Kamera

import { Plugins, CameraResultType } from '@capacitor/core';

const { Camera } = Plugins;

async takePicture() {
  const image = await Camera.getPhoto({
    quality: 90,
    allowEditing: true,
    resultType: CameraResultType.Uri
  });

  var imageUrl = image.webPath;
  imageElement.src = imageUrl;
}
JavaScript

Es wird kein zusätzliches, externes Plugin von Drittanbieter benötigt.

Und das Beste: Dieser Code funktioniert auf iOS, Android, im Desktop über Electron und sogar im Browser. Write once, run everywhere!

Individueller nativer Code

Wer schon einmal unter Cordova versucht hat eigenen nativen Code über Cordova-Plugins in das Projekt zu integrieren, weiß um die Probleme und Komplexität. Einen schönen Gruß aus der Entwickler-Hölle. Doch mit Capacitor gibt es auch hier einen Lichtblick: Individueller nativer Code kann extrem einfach in das eigene Projekt integriert und im Javascript-Code genutzt werden.

Dazu muss im nativen Projekt in Xcode lediglich eine beliebiege Swift-Datei, z.B. myNativeCode.swift erstellt werden:

import Capacitor

@objc(MyNativeCode)
public class MyNativeCode: CAPPlugin {
  @objc func echo(_ call: CAPPluginCall) {
    let value = call.getString("value") ?? ""
    call.success([
        "value": value
    ])
  }
}

C-like

Im Anschluss muss lediglich in einer gleichlautenden Objective-C-Datei (ohne Header-Datei) MyNativeCode.m nur noch die neue Funktionalität registriert werden:

#import <Capacitor/Capacitor.h>

CAP_PLUGIN(MyNativeCode, "MyNativeCode",
  CAP_PLUGIN_METHOD(echo, CAPPluginReturnPromise);
)
C-like

Und schon kann in Javascript auf die native Funktion zugegriffen werden. Einfach und flexibel. Damit können in einem Ionic-Capacitor-Projekt auch Webentwickler und native App-Entwickler Hand in Hand parallel an einem Projekt arbeiten. Benötigte externe Frameworks oder SDKs können direkt in der nativen Umgebung eingerichtet und genutzt werden.

So einfach und flexibel kann hybride App-Entwicklung heute sein!

Das Beste kommt zum Schluss: Cordova-Plugins können weiter genutzt werden

Das Ionic Team hat hervorragende und sehr entwickler-orientierte Arbeit geleistet. Capacitor ist voll abwärtskompatibel zu Cordova. Der Vorteil von Cordova ist die lange Geschichte, der großen Community und die damit goße Verbreitung von Plugins. Und auf diese Vorteile muss bei der Capacitor nicht verzichtet werden. Cordova-Plugins können direkt in Capacitor eingebunden und genutzt werden, ohne auf den vereinfachten Entwicklungsprozess verzichten zu müssen. Um ein (externes) Cordova-Plugin verwenden zu können, müssen lediglich folgende Befehle eingeben werden:

npm install cordova-plugin-scanbot-sdk
npx cap sync
Markup

Die Typescript-Implementationen von Ionic Native können natürlich ebenso verwendet werden:

npm install cordova-plugin-applepay npm install --save @ionic-native/apple-pay npx cap sync
Markup

One more thing…

Ach fast hätten wir noch was vergessen. Mit Capacitor können nicht nur iOS- und Android-Apps, sondern auch Desktop-Apps und Progressive Webapps. Ohne weitere Plugins oder Zusatzmodule werden mit einem Quellcode folgende Plattformen mit den jeweiligen nativen Schnittstellen unterstützt:

  • iOS
  • Android
  • Desktop Apps für Windows, Mac und Linux über Electron
  • Progressive Webapps


Das Fazit der App-Agentur:
Capacitor und Ionic bündelt nun wirklich das beste aus beiden Welten. Aus der nativen und webbasierten Welt. Der Entwicklungsprozess für hybride Apps wurde extrem vereinfacht, Abhängigkeiten wurden gelöst und der Zugriff auf native Funktionen optimiert. Webentwickler und native Entwickler können endlich wirklich parallel in ihrer Welt Hand in Hand an einem Projet arbeiten.

Neue Funktionen und Updates der nativen Entwicklungsumgebungen direkt genutzt werden. Die Geschichte der hybriden App-Entwicklung hat neu begonnen. Es gibt keinen Grund Capacittor nicht zu nutzen.

Write once, run everywhere!

Interesse an einer kosteneffizienten Umsetzung einer mobilen App mit Ionic und Capacitor?

AREA-NET GmbH
Werbeagentur, Internetagentur und App Agentur
Öschstraße 33 | 73072 Donzdorf | Kreis Göppingen