Teil 2: Das Erstellen einer Hybrid-App

Ionic: So erstellt man Hybrid-Apps
Kommentare

Hybrid-Apps sind auf dem Weg, doch noch zur großen Verheißung zu werden: Dank jüngster Weiterentwicklungen der Mobile-Technologien setzt ein Framework nun zur echten Revolution an Ionic. Im zweiten Teil der Artikelserie beschäftigen wir uns damit, wie man eine Hybrid-App erstellt. Als Vorbild dient uns die Beispiel-App Vibrations.

Lesen Sie hier den ersten Teil dieser Artikelserie: Ionic: Einführung in das Erstellen von Hybrid-Apps.

Im Folgenden beschreibt der Artikel das Vorgehen bis zu einer fertigen App anhand der Beispiel-App Vibrations. Es handelt sich um eine kleine CRUD-Applikation, die Vibrationen des mobilen Geräts von konfigurierbarer Länge ausführen kann. Folgender Befehl erzeugt das App-Skeleton im Unterverzeichnis vibrations/:

$ ionic start --sass vibrations blank

Die Option –sass aktiviert Sass Precompiling, sodass eigene Styles direkt in Sass statt gewöhnlichem CSS geschrieben werden können. Später kann das auch mit ionic setup sass nachgeholt werden. Anstelle des Parameters blank können auch andere Templatekürzel angegeben werden. Die Angabe tabs installiert beispielsweise ein komplexeres App-Skeleton mit Tabnavigation und ui-router-Integration. Eine vollständige Templateliste erhalten Sie mit ionic templates. Eine Auswahl wichtiger Verzeichnisse und Dateien im neuen Projektverzeichnis zeigt Tabelle 1.

Tabelle 1: Auswahl wichtiger Verzeichnis und Dateinamen im neuen Projektverzeichnis

Tabelle 1: Auswahl wichtiger Verzeichnis und Dateinamen im neuen Projektverzeichnis

Im Head des App-Einstiegspunkts www/index.html ist die Einbindung von Ionic, Cordova und eigener Styles bzw. JavaScript zu sehen (Listing 1).

Listing 1

<!-- Kompiliertes CSS aus Ionic- sowie eigener Styles -->
<link href="css/ionic.app.css" rel="stylesheet">

<!-- Ionic JavaScript -->
<script src="lib/ionic/js/ionic.bundle.js"></script>

<!-- Cordova; erzeugt 404 im nicht-mobilen Browser -->
<script src="cordova.js"></script>

<!-- Applikationsspezifisches JavaScript -->
<script src="js/app.js"></script>

Nach dem Wechsel ins Projektverzeichnis startet ionic serve den integrierten Webserver und lädt die App zu Entwicklungszwecken im Browser. Der Webserver läuft standardmäßig im Live-Reload-Modus. Zusammen mit einem gulp-Watcher für Sass Precompiling können Sie alle Änderungen an HTML, JavaScript und Sass daher ohne Reload im Browser sehen. Dort stehen Ihnen die gewohnten Debugging-Werkzeuge Ihres Browsers zur Verfügung. ionic serve — lab lädt eine Split-View für die verschiedenen Plattformen, sodass eventuelle Unterschiede von UI-Komponenten sichtbar werden. Der Titel einer App wird in iOS etwa standardmäßig mittig angezeigt, in Android linksbündig (Abb. 1).

Abb. 1: Anzeige des App-Titels in iOS und Android

Abb. 1: Anzeige des App-Titels in iOS und Android

SDKs, Simulatoren und App-Previews

Ein Build erzeugt aus einem Ionic-Projekt eine installierbare native App. ionic build erstellt einen neuen Build, ionic run baut und installiert direkt auf ein angeschlossenes Gerät, und ionic emulate baut und startet die App im Simulator. Möchten Sie lokale App-Builds für iOS durchführen, benötigen Sie Mac OS X und die Xcode-Entwicklungsumgebung. Zur Verwendung des iOS-Simulators müssen Sie zudem das Node Package ios-sim installieren:

sudo npm -g install ios-sim

Möchten Sie lokale App-Builds für Android durchführen, benötigen Sie das Android-SDK. Die Installation inklusive Java und Ant geht nicht auf jedem System leicht von der Hand. Alle nötigen Tipps und Links finden Sie in den Ionic-FAQs. Das Android-SDK liefert zur Verwaltung angeschlossener Android-Geräte das sehr nützliche Kommandozeilenwerkzeug Android Debug Bridge ADT mit. Damit können Sie ein oder mehrere angeschlossene Geräte identifizieren, Apps/Daten aufspielen und entfernen, Logs ansehen und vieles mehr. Beachten Sie, dass dazu auf Android-Geräten der Debugging-Modus aktiviert sein muss. Für gewöhnlich drücken Sie dazu im Einstellungsmenü „Über das Telefon“ siebenmal auf die Build-Nummer. Geräte im gleichen Netzwerk können mittels Android Debug Bridge auch über WLAN angeschlossen werden (ADB Wireless).

Der native Android-Emulator bereitet aufgrund mangelnder Performance jedem Schmerzen, der ihn einmal benutzt hat. Hier schafft Genymotion Abhilfe. Etliche Android-Devices können als virtuelle Maschinen unter VirtualBox gestartet und wie physikalisch angeschlossene Geräte genutzt werden. Zum Testen muss eine App daher mit ionic run statt ionic emulate aufgespielt werden. Ohne lokales SDK können mit dem Befehl ionic package Builds in der Cloud ausgeführt werden.

App testen

Um aus dem bisherigen Code eine native App zu erzeugen, müssen zunächst die gewünschten Zielplattformen hinzugefügt werden:

$ ionic platform add ios
$ ionic platform add android

Das erzeugt in den Verzeichnissen platforms/ios bzw. platforms/android die nativen App-Strukturen. Der Befehl ionic emulate ios –live-reload startet die App im iOS-Emulator (Abb. 2) und aktiviert wie im Browser den praktischen Live-Reload-Modus, sodass Änderungen am Code live auf dem Emulator verfolgt werden können. Zum Debugging kann der Safari Web Inspector über das Menü Entwickler | iOS Simulator | IP-Auswahl verwendet werden.

Abb. 2: iOS-Emulator

Abb. 2: iOS-Emulator

Bei zwei mit Genymotion aufgesetzten Android-Maschinen können Sie die Ziel-IPs mit adb ausfindig machen:

$ adb devices
List of devices attached 192.168.59.103:5555    device
192.168.59.104:5555    device

Anschließend kann die App ebenso kompiliert und im Live-Reload-Modus gestartet werden (Abb. 3):

$ ionic run android --live-reload --target=192.168.59.104:5555
Abb. 3: Live-Reload-Modus auf Android

Abb. 3: Live-Reload-Modus auf Android

In diesem Fall ist run statt emulate zu verwenden, um nicht den oben beschriebenen langsamen Android-Emulator des SDKs zu starten. Android-Apps können ab Android 4.4 (bzw. mit Crosswalk-Unterstützung auch in früheren Versionen) mit den gewohnten Chrome DevTools debuggt werden. Geben Sie in der Chrome-Adresszeile chrome://inspect ein und wählen Sie auf dem gewünschten angeschlossenen Device die passende WebView aus (Abb. 4).

Abb. 4: Debugging mit den Chrome DevTools

Abb. 4: Debugging mit den Chrome DevTools

Das Testen von Apps ist auf Android-Geräten deutlich einfacher als in iOS. Dort müssen Sie sich zunächst für 99 US-Dollar pro Jahr im Apple Developer Program registrieren, Zertifikate installieren und schließlich das Verzeichnis platforms/ios als Projekt in Xcode öffnen und von dort aus installieren.

Beispiel-App erweitern

Erweitern wir die Applikation in der index.html um einen Angular-Controller VibrationsCtrl, einen passenden Titel und die Anzeige einer Liste von „Vibrationen“ mit Name und Dauer in Millisekunden. Für die Liste wird die Ionic-Komponente ion-list verwendet, die das Verhalten einer nativen Liste von Elementen nachbildet (Listing 2).

Listing 2

<body ng-app="starter" ng-controller="VibrationsCtrl">
  <ion-pane>
    <ion-header-bar class="bar-stable">
      <h1 class="title">PHPmagazin: Vibrations</h1>
    </ion-header-bar>
    <ion-content>
      <ion-list>
        <ion-item ng-repeat="vibration in vibrations">
         {{ vibration.name }}: {{ vibration.duration }}ms
        </ion-item>
      </ion-list>
    </ion-content>
  </ion-pane>
</body>

Bei HTML-Elementen mit dem Präfix ion- handelt es sich um Ionic-UI-Komponenten, die als Angular-Direktiven implementiert sind. ion-pane, ion-header-bar und ion-content etwa sind Komponenten, die die Ansicht strukturieren und Standards wie korrektes Scrollverhalten und passende Abstände implementieren. Weiterhin bietet Ionic von Action Sheets, Formularelementen, Headern und Footern, über Navigationen bis Pop-ups und Spinnern fast alles, was man von nativen Apps her gewohnt ist. Falls benötigt, erlaubt Dependency Injection den programmatischen Zugriff auf die Komponenten. Funktionen von ion-list lassen sich etwa über $ionicListDelegate steuern, Pop-ups oder Modals über $ionicPopup bzw. $ionicModal. Mit der passenden Controller-Methode in App.js kann eine Liste von Vibrationen in der index.html gerendert werden (siehe auch Abb. 5 und Listing 3). Listing 4 zeigt, wie der Code um einige Buttons zum Anlegen und Löschen von Vibrationen erweitert werden kann.

Listing 3

angular.module('starter', ['ionic'])
// ...
.controller('VibrationsCtrl', function($scope){
  $scope.vibrations = [
    { name: ‚Foo', duration: 800 },
    { name: ‚Bar', duration: 240 },
 
    { name: ‚Baz', duration: 499 }
  ];
})
Abb. 5: Liste von Vibrationen in index.html

Abb. 5: Liste von Vibrationen in index.html

Listing 4

<ion-pane>
  <ion-header-bar class="bar-stable">
    <div class="buttons">
      <button class="button button-icon ion-ios-minus-outline"
        ng-click="listConfig.showDelete=!listConfig.showDelete">
      </button>
    </div>
    <h1 class="title">PHPmagazin: Vibrations</h1>
    <div class="buttons">
      <button class="button button-icon ion-ios-plus-outline" ng-click="new()"></button>
    </div>
  </ion-header-bar>
  <ion-content>
    <ion-list show-delete="list.showDelete">
      <ion-item ng-repeat="vibration in vibrations">
        <ion-delete-button class="ion-minus-circled"
          ng-click="delete(vibration)">
        </ion-delete-button>
      {{ vibration.name }}: {{ vibration.duration }}ms
      </ion-item>
    </ion-list>
  </ion-content>
</ion-pane>

Die CSS-Klassen, z. B. in der ion-header-bar oder im button-Element, zeigen beispielhaft die View-Gestaltung in Ionic; alle Details zeigt die CSS-Dokumentation. In der ion-header-bar wird links ein Button platziert, der die Sichtbarkeit der Löschbuttons für die einzelnen Listenelemente steuert. Klickt der User diesen Button, erscheinen – wie aus nativen Apps gewohnt – animierte Löschbuttons in jedem Listenelement, repräsentiert durch ion-delete-button-Elemente. Getriggert wird das Ein- und Ausblenden über einen Boolean-Wert für das show-delete-Attribut des ion-list-Elements (Abb. 6). Rechts in der ion-header-bar wird ein Button zur Erstellung einer neuen Vibration angezeigt. Ein Tap hierauf öffnet ein modales Fenster mit einem Formular, das die Anlage eines neuen Listenelements mit Name und Vibrationsdauer ermöglicht (Abb. 7). Der Inhalt des modalen Fensters wird in einem script-Template im Anschluss an den vorigen Code definiert (Listing 5). In der app.js wird entsprechend der Controller erweitert (Listing 6).

Listing 5

<script id="create.html" type="text/ng-template">
  <ion-modal-view>
    <ion-header-bar>
      <h1 class="title">Create New Vibration</h1>
      <button class="button button-clear" ng-click="close()"> Cancel</button>
    </ion-header-bar>
    <ion-content>
      <form ng-submit="create(vibration)">
        <div class="list">
          <label class="item item-input">
            <input type="text" placeholder="Name" ng-model="vibration.name"></label>
          <label class="item item-input">
            <input type="text" placeholder="Duration" ng-model="vibration.duration">
          </label>
        </div>
        <div class="padding">
          <button type="submit"
              class="button button-block button-primary"> Create Vibration</button>
        </div>
      </form>
    </ion-content>
  </ion-modal-view>
</script>

Listing 6

.controller('VibrationsCtrl', function($scope, $ionicPopup, $ionicModal){
    $scope.vibrations = ...;

    $scope.listConfig = { showDelete: false
    };

    $scope.delete = function(item) {
      $scope.vibrations.splice($scope.vibrations.indexOf(item), 1);
    };

    $scope.vibration = { name: '', duration: ''
    };

    $ionicModal.fromTemplateUrl('create.html', function(modal) {
      $scope.createModal = modal;
    }, {
      focusFirstInput: true, scope: $scope
  });

  $scope.new = function() {
    $scope.createModal.show();
  };

  $scope.close = function() {
    $scope.createModal.hide();
  };

  $scope.create = function(vibration) {
    if (!vibration.name || !vibration.duration) {
      $ionicPopup.alert({
        title: 'Validation Error',
        template: 'Please enter name and duration'
      });
      return;
    }
    $scope.vibrations.push(angular.copy(vibration));
    $scope.createModal.hide();


  };
});

vibration.name = vibration.duration = '';

Besonders interessant ist die Injizierung der beiden Ionic-Services $ionicPopup und $ionicModal in die Controller-Funktion. $ionicModal.fromTemplateUrl() initialisiert das oben beschriebene script-Template als modales Fenster, das sich im Anschluss mit show() und hide() ein- und ausblenden lässt. In der vereinfachten Formularvalidierung zum Anlegen einer neuen Vibration wird ein Validierungsfehler ggf. mithilfe von $ionicPopup in einem Pop-up angezeigt.

Im dritten und letzten Teil dieser Artikelserie (erscheint morgen) möchte ich Ihnen zeigen, wie man die Beispiel-App um weitere Spezifikationen und eigene Styles erweitert. Zudem lernen Sie, die entwickelte App auf Usability und Performance zu testen.

Überblick zur Ionic-Artikelserie:

Teil 1: Einführung in das Erstellen von Hybrid-Apps
Teil 2: So erstellt man Hybrid-Apps
Teil 3: Spezifikationen und Testen von Hybrid-Apps

 

Auf der MobileTech Conference 2015 in Berlin gibt es vom 31. August bis 3. September jede Menge interessanter Sessions – auch zum Thema Cross-Plattform-Entwicklung mit Ionic:

 

 

PHP Magazin

Entwickler MagazinDieser Artikel ist im PHP Magazin erschienen. Das PHP Magazin deckt ein breites Spektrum an Themen ab, die für die erfolgreiche Webentwicklung unerlässlich sind.

Natürlich können Sie das PHP Magazin über den entwickler.kiosk auch digital im Browser oder auf Ihren Android- und iOS-Devices lesen. In unserem Shop ist das Entwickler Magazin ferner im Abonnement oder als Einzelheft erhältlich.

Aufmacherbild: Modern mobile instant messenger chat poster via Shutterstock / Urheberrecht: Macrovector

Unsere Redaktion empfiehlt:

Relevante Beiträge

Meinungen zu diesem Beitrag

X
- Gib Deinen Standort ein -
- or -