Aus Linux-Magazin 06/2018

Apps mit React Native und Nativescript entwickeln

© Leonid Tit, 123RF

Die Javascript-Frameworks React Native und Nativescript versuchen eine Brücke zwischen Webapp-Entwicklung und nativer App-Entwicklung zu bauen. Worin die Vorteile dieser Native Frameworks liegen, betrachtet der Artikel vor dem Hintergrund des klassischen App-Framework Meteor.

Die beiden quelloffenen Javascript-Frameworks React Native [1] und Nativescript [2] erlauben es, mit Hilfe eigener IDEs mit Javascript native Apps für Android und I-OS zu entwickeln. Der Ansatz hat Vorteile gegenüber dem Weg der klassischen Webapp-Entwicklung, den etwa das Javascript-Framework Meteor [3] verfolgt, das auf Apache Cordova [4] und Webview setzt.

Ausgangslage

Native Apps für Android programmieren Entwickler traditionell mit Java oder Kotlin, für I-OS ziehen sie Objective-C oder Swift [5] heran. Weil Android-Apps intern über C oder C++ auf nativen Code zugreifen, stützen sich Entwickler dafür beispielsweise auf das Java Native Interface (JNI, [6]). Die Entwicklungsumgebungen Android Studio [7] und Xcode [8] helfen ihnen dabei, die Anwendung zu programmieren und in die entsprechenden App-Stores zu bringen.

Dieser Weg hat allerdings einen Nachteil: Das Installieren von Android Studio ist recht aufwändig und Xcode läuft exklusiv auf Apples Betriebssystem OS X. Wer zudem eine Android-App für I-OS übernehmen möchte, muss den Code unter Ojective-C oder Swift eins zu eins nachprogrammieren. Das erhöht jedoch den Entwicklungsaufwand deutlich und schafft wegen der Code-Redundanz zusätzliche Fehlerquellen.

Klassische Webapps nutzen hingegen HTML, CSS und Javascript und laufen plattformübergreifend im Browser jedes Systems. Allerdings beschränken die Plattformen den Zugriff auf das System mit Hilfe der so genannten Browser-Sandbox und geben APIs nur punktuell frei, was die Fähigkeiten von Webapps beschränkt.

2009 erschien dann Phone Gap (heute Apache Cordova). Mit ihm lassen sich Webapps besser an das System anbinden. Unter Cordova laufen Apps in einer Webansicht auf dem System wie in einem Browser. Plugins erweitern den Zugriff auf das System für die Apps.

Meteor

Ein Vertreter dafür ist das Javascript-Framework Meteor [3]. Es hat sich von einem Framework zum Entwickeln echtzeitfähiger Webapps [9] zu einer Open-Source-Plattform entwickelt, die von sich behauptet der schnellste Weg zu sein, um Apps an den Start zu bringen.

Tatsächlich fällt das Installieren und Erzeugen einer Bootstrap-App über

curl https://install.meteor.com/ | sh meteor create example

in der Shell unter Ubuntu 17.10 noch recht leicht. Das Bauen der App für Android mit dem Befehl »meteor add-platform android« bricht aber bereits mit den Fehlermeldungen aus Abbildung 1 ab. Denn intern verwendet Meteor Cordova, das nach Java und Android Studio verlangt. Ein Build für I-OS ist unter Ubuntu ohnehin nicht möglich.

Abbildung 1: Cordova: Ohne Java und Android Studio läuft für Android-Entwickler unter Ubuntu nichts.

Abbildung 1: Cordova: Ohne Java und Android Studio läuft für Android-Entwickler unter Ubuntu nichts.

Immerhin darf der Benutzer beim Erzeugen der App zwischen Meteors eigenem Javascript-Framework Blaze, Angular [10] sowie React [11] wählen. Beim Deployment unterstützt Meteor den Programmierer aber schon weniger. Zwar paketiert »meteor build« Versionen für Android und I-OS, anschließend braucht es jedoch einige Handarbeit, um die Apps in den jeweiligen App-Store zu befördern.

React Native

Native Frameworks wählen im Vergleich dazu einen etwas anderen Ansatz. Sie versprechen native Apps für Android und I-OS auf Javascript-Basis. Sie schlagen damit eine Brücke zwischen Webapps und plattformspezifischen Apps.

Das Framework React Native [1] überlässt zur Laufzeit der Javascript-Engine das zugrunde liegende System. Der Code läuft in einem eigenen Thread und greift über eine Brücke (Abbildung 2, [12]) auf native APIs und nativen Code des Systems zu. So entsteht die grafische Benutzerschnittstelle nicht wie unter Meteor über den DOM-Baum der Webview, sondern über Aufrufe nativer UI-Widgets in Java oder Objective-C.

Abbildung 2: Eine Brücke verbindet die Javascript-Welt mit nativem Code.

Abbildung 2: Eine Brücke verbindet die Javascript-Welt mit nativem Code.

Löst der Benutzer umgekehrt beim Bedienen der gerenderten Elemente Events aus, reicht das React-Native-System diese über die Brücke zurück und verwandelt sie in ein Javascript-Event. Performance-Einbußen, die beim Synchronisieren beider Welten entstehen, wirkt React Native mit einem virtuellen DOM entgegen. Das Vorbild dafür liefert das gleichnamige Javascript-Framework React. Im Praxistest reagierten die Beispiel-Apps von React Native ungefähr so träge wie native Apps unter einer älteren I-OS-Version.

Will der Entwickler React-Native-Apps entwerfen, hilft ihm das Projekt Expo [13] mit einer Reihe von Tools. Dazu zählt die Entwicklungsumgebung XDE, sie startet unter dem Namen Snack [14] auch im Browser. Zugleich lässt sie sich nach dem Ausführen der Installationsanweisungen aus Listing 1 über die Kommandozeile in der Shell bedienen.

Listing 1

Expo unter Ubuntu 17.10 installieren

01 curl -sL https://deb.nodesource.com/setup_8.x |  sudo -E bash -
02 sudo apt-get install nodejs
03 sudo npm install exp --global
04 exp init react-test
05 cd react-test
06 exp start

Die Zeilen 1 und 2 installieren die aktuelle Version von Node 8 über Debians Paketmanager Apt. Nodes Paketmanager Npm holt dann in Zeile 3 Expo (»exp«) inklusive React Native auf das System, bevor Zeile 4 die Boilerplate-Anwendung »react-test« einrichtet. Die Zeilen 5 und 6 packen die App zum Laden via Smartphone – Abbildung 3 zeigt die Shell nach dem Ausführen der Befehlskette samt einem QR-Code zur Installation.

Abbildung 3: Expo bietet die App zum Laden im Expo-Client wie eine Website an.

Abbildung 3: Expo bietet die App zum Laden im Expo-Client wie eine Website an.

Um die gepackte App über den QR-Code auf ein Android-Gerät oder iPhone zu befördern, muss der Nutzer zuvor aus dem entsprechenden App-Store den gleichnamigen Expo-Client auf dem Gerät installieren. Er startet den Client, scannt den QR-Code und lädt anschließend die Boilerplate-App wie in Abbildung 4.

Abbildung 4: Die App bedient sich der Klasse »UIAlertController« unter I-OS.

Abbildung 4: Die App bedient sich der Klasse »UIAlertController« unter I-OS.

Überschreiten die Anforderungen an eine App auch die Grenzen des mit React Native und Expo Realisierbaren, rüstet der Benutzer nativen Code nach, um ihn über Javascript in seiner App fernzusteuern. In diesem Fallback-Szenario muss er allerdings Android Studio und Xcode nachinstallieren.

Beispiel einer App

Wie Entwickler React Native einsetzen, deutet Listing 2 an. Den Code speichert die Datei »App.js« im Verzeichnis »react-test«. Wie jede Anwendung unter React Native basiert auch Listing 2 auf dem Javascript-Framework React [11], Zeile 1 importiert es. Zeile 2 holt dann die Komponenten »Style«, »Button«, »View« und »NetInfo« aus React Native.

Listing 2

React-Native-Beispiel-App

01 import React from 'react';
02 import { StyleSheet, Button, View, NetInfo } from 'react-native';
03
04 export default class App extends React.Component {
05   render() {
06     return (
07       <View style={styles.container}>
08         <Button title="Connection Info" onPress={this.getConnectionInfo}/>
09       </View>
10     );
11   }
12   getConnectionInfo() {
13     NetInfo.getConnectionInfo().then(info => alert(info.type+' ('+info.effectiveType+')'));
14   }
15 }
16
17 const styles = StyleSheet.create({
18   container: {
19     flex: 1,
20     backgroundColor: '#ddd,
21     alignItems: 'center',
22     justifyContent: 'center',
23   },
24 });

Auch die Basisklasse App (Zeilen 4 bis 16) bildet React Native als Komponente. Deren Render-Methode (Zeilen 5 bis 11) erstellt mit dem XML-ähnlichen JSX-Code ein bereichsbezogenes User-Interface (Zeilen 7 bis 9). In Zeile 8 kapselt die Komponente »View« einen Button [15]. Den setzt Android zur Laufzeit mit einer Instanz der Klasse »android.widget.Button« um [16]. Unter I-OS kommt dagegen »UIButton« [17] zum Einsatz.

Die Zeilen 13 bis 15 speichern die Callback-Funktion »getConnectionInfo()«, auf die der Wert des Attributs »onPress« verweist. Beim Knopfdruck ermittelt die gleichnamige Methode in Zeile 15 den Verbindungsstatus des Mobilgeräts.

Auf das asynchron eintreffende Ergebnis reagiert die Lambda-Funktion mit dem Aufruf der Methode »then()«. Eigentlich soll sie den ermittelten Verbindungstyp in einer Alert-Box melden. Wie Abbildung 4 zeigt, ließ sich der Verbindungsstatus im Praxistest aus unbekanntem Grund nicht ermitteln.

Die Codereferenz »{styles.container}« aus dem Wert des Attributs »style« bindet in Zeile 7 die Stylesheet-Angaben aus dem statischen Javascript-Objekt »styles« an die Komponente »View«. Die Angaben färben den Hintergrund in einem Grauton und platzieren den Knopf im Zentrum des Displays. Neben »NetInfo« bietet React Native noch eine Reihe weiterer systembezogener API-Objekte, die Expos so genanntes SDK noch einmal erweitert.

Der Befehl »exp start« in der letzten Zeile von Listing 1 startet unter anderem einen so genannten Watch-Prozess. Registriert der eine Änderung am Projektverzeichnis, informiert er den ebenfalls gestarteten Packager-Server. Er veranlasst ihn, die aktualisierte App an verbundene Expo-Clients auszuliefern.

Wie die Beispiel-App »react-test« [18] demonstriert, darf ein Programmierer eine App jederzeit kostenlos unter seinem Expo-Account im Cloudspeicher des Projekts veröffentlichen. Dies stößt er an, indem er in der XDE-IDE auf den Publish-Button klickt. Ergänzt er zudem unter dem Projektverzeichnis die Konfigurationsdatei »app.json« passend um die Angaben »buildidentifier« und »package«, erzeugt »exp build:android« etwa eine Android-App innerhalb der Anbieter-Cloud.

Das Buildlog des Prozesses verfolgt der Entwickler beim Einsatz des CLI über eine URL unter dem Expo-Account live mit. Abbildung 5 zeigt das Buildlog nach dem erfolgreichem Bau des Android-Pakets. Hinter den Kulissen verwendet Expo Instanzen von Android Studio oder Xcode aus ihrer Cloud. Wie unter Meteor haben die Anbieter aber die letzten Meter in den App-Stores nicht vollständig automatisiert, hier fällt wieder einige Handarbeit an.

Abbildung 5: Expo gew&auml;hrt Einblick in die Logfiles seiner Cloudbuilds.

Abbildung 5: Expo gewährt Einblick in die Logfiles seiner Cloudbuilds.

Nativescript

Auch das Javascript-Framework Nativescript [2] verspricht native Apps für Android und I-OS auf den Weg zu bringen. Wie React Native überlässt es auch Nativescript der jeweiligen Javascript-Engine, den Code auszuführen. Dabei kommen unter Android V8 und unter I-OS JSC zum Einsatz.

Auch Nativescript steuert nativen Code über eine Brücke [19] fern. Dabei reicht die Laufzeitumgebung Aufrufe von Getter- und Setter-Methoden eines Javascript-Objekts dynamisch an native Objekte weiter.

Die Entwicklungsumgebung für Nativescript aufzusetzen erweist sich unter Linux als besonders dornenreich. Builds von I-OS-Apps fallen aus bekannten Gründen ohnehin aus. Wer Kosten (siehe Tabelle 1) nicht scheut, lässt die Apps wie unter Expo in der Cloud des Anbieters erstellen. Zumindest die ersten 100 Builds sind kostenfrei.

Tabelle 1

Feature-Vergleich

Framework

IDE

Cloudbuilds

Natives UI

Native Module

Packen nativer Formate

App-Store-Deployment

Meteor 1.6.1

nein

nein

nein

ja

ja

nein

React Native 52.0

XDE 2.22.1

ja

ja

ja

ja

nein

Nativescript 3.4.3

Sidekick 1.5.1

kostenpflichtig

ja

ja

ja

nein

Der Befehl »sudo npm install -g nativescript« installiert das Javascript-Framework unter Ubuntu in der Shell. Eine geeignete Bootstrap-App erstellt dann:

tns create ns-test --template  nativescript-template-ng-tutorial

Die grafische Entwicklungsumgebung Sidekick [20] installiert Debians Paketmanager Dpkg nach dem Download über »sudo dpkg -i NativeScriptSidekick-amd64.deb«. Anschließend startet Sidekick über einen Aufruf aus der Shell heraus:

/opt/Native\ Script\ Sidekick/Native\  Script\ Sidekick

Beim Programmieren der Apps unterstützt Nativescript im Gegensatz zu React Native allerlei Skriptsprachen und Frameworks: Neben Angular [10] und Vue.js [21] lässt sich auch pures Javascript oder Typescript [22] verwenden.

Listing 3 reanimiert die Beispiel-App aus Abbildung 4 und Listing 2 unter Angular und Nativescript. Der Code landet unter der zuvor angelegten Bootstrap-App im Verzeichnis »ns-test« in der Datei »app/app.component.ts«. Zeile 1 von Listing 3 importiert die Klasse »Component« aus Angular, Zeile 2 das Objekt »Connectivity« aus Nativescript. Der Dekorator der Zeilen 4 bis 7 überführt die anschließende Klassendefinition der Basisklasse »AppComponent« (Zeilen 8 bis 22) in eine Ableitung der Klasse »Component«.

Listing 3

Beispiel-App unter Nativescript

01 import { Component } from "@angular/core";
02 import * as connectivity from "connectivity";
03
04 @Component({
05   selector: "my-app",
06   template: `<Button text="Connection Info" (tap)="getConnectionInfo()"></Button>`
07 })
08 export class AppComponent {
09   getConnectionInfo() {
10     switch(connectivity.getConnectionType()) {
11       case 0:
12         alert('none');
13         break;
14       case 1:
15         alert('WiFi');
16         break;
17       case 2:
18         alert('Mobile');
19         break;
20     }
21   }
22 }

Das bereichsbezogene UI erzeugt Zeile 6, indem sie über die Komponente »Button« einen Knopf generiert, der beim Antippen die Callback-Funktion »getConnectionInfo()« bemüht. Der Nativescript-Code ermittelt den Verbindungstyp auf synchronem Weg. Die Funktion »alert()« meldet dem Nutzer das Ergebnis.

Abbildung 6: Sidekick nach dem Cloudbuild f&uuml;r Android. Der f&uuml;r I-OS ist mittlerweile kostenpflichtig.

Abbildung 6: Sidekick nach dem Cloudbuild für Android. Der für I-OS ist mittlerweile kostenpflichtig.

Abbildung 6 zeigt den erfolgreichen Cloudbuild der App mit Hilfe von Sidekick für Android. Den Cloudbuild für I-OS hat die Redaktion nicht getestet, da das benötigte I-OS-Entwicklerzertifikat – anders als dokumentiert – mittlerweile kostenpflichtig ist.

Fazit

Meteor-Apps lassen sich dank des Clouddienstes Galaxy einfach einrichten und skalieren. Nur beim Erzeugen mobiler Apps hapert es. Da ist der direkte Konkurrent Ionic [23] schon weiter.

React Native und Nativescript bieten gleichwertige Lösungsansätze. Sie verzichten auf die Webview und nutzen nativen Code für die Interfaces ihrer I-OS- und Android-Apps. Native-APIs und UI-Komponenten steuern beide über eine Brücke an. Für App-Entwickler fühlt sich das wie unter einem Browser und DOM an, zugleich verbessern die nativen UIs das Benutzererlebnis.

Zudem ergänzt das Expo-Projekt React Native geschickt. Es bietet mit dem Expo-Client, der Web-basierten IDE Snack und dem kostenlosen Cloudspeicher eine ideale Umgebung für neue Projekte und ihre Community. Dank Cloudbuilds müssen die Entwickler zudem keine lästigen Konfigurationsarbeiten und Installationsmühen mit Android Studio und Xcode mehr auf sich nehmen.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 5 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
LINUX-MAGAZIN KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Readly Logo
E-Mail Benachrichtigung
Benachrichtige mich zu:
0 Kommentare
Älteste
Neuste Beste Bewertung
Nach oben