Diese Präsentation zeigt wie man Hybrid Apps mit dem Ionic 2 Framework erstellt kann. Dazu wird eine Beispielapp auf Basis der Open Movie Database programmiert.
14. npm --version Version con NPM abrufen
npm help {befehl} Ruft die Hilfe für den entsprechenden Befehl auf
npm install [-g] {Paketname} Installiert das Paket im aktuellen Projekt bzw. global
npm install {Paketname}@{Version} Installiert das Paket mit der entsprechenden Version in das aktuelle Projekt.
--save Das Paket wird in die Liste der Abhängigkeiten des Projekts eingetragen
--save-dev
Das Paket wird in die Liste der Abhängigkeiten des Projekts eingetragen die zur
Entwicklungszeit gelten.
--force Das Paket wird installiert selbst wenn es schon vorhanden ist.
npm list Zeigt alle installierten Pakete im aktuellen Projekt an.
npm view {Paketname} Ruft diverse Informationen zum angegebenen Paket ab.
npm view {Paketname} {Detailbezeichnung} Ruft nur die Detailinformationen ab (bspw. Versions)
npm update
Aktualisiert alle Pakete des aktuellen Projekts die als Abhängigkeiten gespeichert
wurden.
npm update [-g] {Paketname}[@{Version}]
Aktualisiert das gegebene Paket ggf. auf eine bestimmte Version oder auf die
neuste.
npm uninstall {Paketname} Deinstalliert das angegebene Paket.
--save Entfernt das Paket aus den Projektabhängigkeiten.
--save-dev Entfernt das Paket aus den Projektabhängigkeiten für die Entwicklungszeit.
Die wichtigsten Befehle für NPM im Kontext von Ionic
15. ionic start {AppName} blank --v2 Leeres Projekt für Ionic 2 erstellen.
ionic start {AppName} tabs Projekt mit Tab Template für Ionic 1 erstellen.
ionic start {AppName} sidemenu Projekt mit Sidemenu Template für Ionic 1 erstellen.
ionic platform add android/ios Android bzw. iOs als Plattform hinzufügen.
ionic platform list Zeigt alle installierten Plattformen an.
Ionic platform remove {platform} Entfern die angegebene Plattform.
ionic build android/ios Plattform bauen.
ionic emulate android/ios Plattformversion im Emulator starten.
ionic run android/ios Plattformversion auf Gerät starten.
ionic serve
--lab
--consolelogs |-c
--serverlogs |-s
App im Browser ausführen.
App im Browser mit Ansichten für iOS und Android ausführen.
Ausgabe des Consolen loggings in der CLI.
Server Logs in der CLI ausgeben.
ionic login Bei den Ionic Services anmelden.
ionic upload Die aktuelle App in die Ionic Cloud hochladen.
ionic share Die aktuelle App über die Ionic Cloud mit anderen Personen teilen.
ionic --help Auflistung und Erläuterung aller CLI Befehle.
cordova clean Entfernt alle
Die wichtigsten Befehle für Ionic und Cordova
22. Das Bootstrapping wird an zentraler Stelle verwaltet und beim Programmstart eingeleitet.
23. Cordova plugins werden zentral gespeichert und direkt über Ionic verwendet.
Es gibt kein ngCordova!
24. Cordova Plugins u.ä. werden über Hooks in die Applikation eingebunden.
Dies geschieht weitestgehend automatisch.
25. Ionic speichert alle wichtigen Bibliotheken und Frameworks zunächst
im node_modues Verzeichnis.
Zusätzliche Pakete sollten IMMER über NPM installiert werden damit
der Buildprozess korrekt fuktioniert!
26. Splash screens und App Icons können für jedes plattform gesondert
angegeben werden.
Sie werden über die CLI aus einer Vorlage heraus generiert.
27. Type Script 1.x benötigt Typeings um Javascript Frameworks ansprechen zu können.
Diese sind separat mit jedem Framework herunter zu laden.
28. Die eigentliche App wird nach einem ionic build im www Verzeichnis zur Verfügung gestellt.
Im www Verzeichnis sollte nicht entwickelt werden!!!
29. Konfiguration aller wichtigen Umgebungsparameter der App (Version, App Package, API Version, …)
Konfiguration des Buildprozesses
Konfiguration der Ionic Parameter (welche Ionic Version, wird typscript verwendet, …)
NPM und Cordova Config (welche Pakete werden verwendet, Plattformen addressiert, Plugins verwendet)
Konfiguration des Typescript Transpilings (in welche JS Version, welche Dateien, wo liegen die Typings)
Konfiguration des Linters zur statischen Codeanalyse
Registrierung der eigentlichen Typings
35. import {beforeEachProviders, it, describe, expect, inject} from '@angular/core/testing';
import {Movies} from './movies';
describe('movie services', () => {
it('should return true', () => {
expect(true).toBeTruthy();
});
});
1. Füge neue Datei hinzu movies.spec.ts
2. Schreibe folgenden Inhalt in die Datei:
3. npm test
-> Test sollte erfolgreich sein
4. Ändere im test expect(true) zu expect(false)
-> Test sollte fehlschlagen
40. Beispiel lodash
npm install -g typings
npm install lodash --save
typings install lodash –save
import {[Funktionen die verwendet werden]} from 'lodash';
Überall wo es verwendet wird
43. import {beforeEachProviders, it, describe, expect, inject} from '@angular/core/testing';
import {Movies} from './movies';
import {includes, find} from 'lodash';
describe('movie search', () => {
beforeEachProviders(() => [Movies]);
it('should return an array of movies for the search text lo', inject([Movies], (movieRepository) =>{
var movies = movieRepository.search("lo");
expect(Array.isArray(movies)).toBeTruthy;
expect(movies.length).toBeGreaterThan(0);
}));
[2. Test]
});
Der 1. Test
44. Der (Fake)Provider + Domain Object
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
@Injectable()
export class Movies {
constructor() {}
public search(searchText: string) {
let data = new Array();
let movie = {};
movie.Title = "olo";
data.push(movie);
return data;
}
}
export class Movie {
public Title : string;
public Year : number;
public imdbID: string;
public Type: string;
public Poster: string;
}
Beispiel: http://www.omdbapi.com/?s=lo
{
"Title":"The Hi-Lo Country",
"Year":"1998",
"imdbID":"tt0120699",
"Type":"movie",
"Poster":"https://images-na.ssl-images-...
},
46. Der echte Provider
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { Http } from '@angular/http';
@Injectable()
export class Movies {
constructor(private http: Http) {}
public search(searchText: string) {
return new Promise(resolve => {
let url = 'http://www.omdbapi.com/?s=' + searchText;
console.log('start searching:' + url);
this.http.get(url)
.map(result => result.json())
.subscribe(data => resolve(data.Search));
});
}
}
47. it('should return movies which titles contain the text lo', inject([Movies], (movieRepository) => {
var movies = movieRepository.search("lo");
var foundSearchPhrase = find(movies, function(movie) {
var missmatchFound = !includes(movie.Title, 'lo');
return missmatchFound;
});
expect(movies.length).toBeGreaterThan(0);
expect(foundSearchPhrase).toBeFalsy("Found at least one element which does not contain lo.");
}));
Der 2. Test
48. ionic g page Search
Die Search Page – noch ohne Suche (1)
View:
<ion-header>
<ion-navbar>
<ion-title>Search</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<ion-list >
<ion-item *ngFor="let movie of movies">
{{movie.Title}}
</ion-item>
</ion-list>
</ion-content>
Logik:
import { Component } from '@angular/core';
import { Movies } from '../../providers/movies/movies';
@Component({
templateUrl: 'build/pages/search/search.html',
providers: [Movies]
})
export class SearchPage {
public movies: any;
constructor(private movieRepository: Movies) {
this.movieRepository.search("lo").then(data => {
this.movies = data;
});
}}
49. Die Search Page – noch ohne Suche (2)
import { Component } from '@angular/core';
import { ionicBootstrap, Platform } from 'ionic-angular';
import { StatusBar } from 'ionic-native';
import { SearchPage } from './pages/Search/Search';
@Component({
template: '<ion-nav [root]="rootPage"></ion-nav>‚
})
export class MyApp {
rootPage: any = SearchPage;
constructor(public platform: Platform) {
platform.ready().then(() => {
StatusBar.styleDefault();
});
}}
ionicBootstrap(MyApp);
app.ts anpassen
64. Navigationsparameter abrufen
import { Component, OnInit } from '@angular/core';
import { Movies } from '../../providers/movies/movies';
import { NavParams } from 'ionic-angular';
@Component({
templateUrl: 'build/pages/details/details.html',
providers: [Movies]
})
export class DetailsPage implements OnInit{
public movie: any = {};
constructor(private movieRepository: Movies, private params: NavParams) { }
ngOnInit()
{
this.setMovie(this.params.get("id"));
}
…
65. Zurück navigieren
Logik
…
import { NavController } from 'ionic-angular';
@Component({
templateUrl: 'build/pages/search/search.html',
providers: [Movies]
})
export class SearchPage {
public goBack() {
this.navCtrl.pop();
}
constructor(private movieRepository: Movies,
public navCtrl: NavController) {
}
…
<ion-navbar>…</ion-navbar>
66. Navigation ohne Stack
import { App, ViewChild } from '@angular/core';
import { NavController } from 'ionic-angular';
@App({
template: '<ion-nav #myNav [root]="rootPage"></ion-nav>'
})
export class MyApp {
@ViewChild('myNav') nav: NavController
private rootPage = TabsPage;
// Wait for the components in MyApp's template to be initialized
// In this case, we are waiting for the Nav with id="my-nav"
ngAfterViewInit() {
// Let's navigate from TabsPage to Page1
this.nav.push(Page1);
}
}
67. Favorites Page
ionic g page Favorites
<ion-header>
<ion-navbar>
<ion-title>Favorites</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
Hier finden sich irgend wann einmal die beliebtesten Filme des Nutzers.
</ion-content>
69. About Page
ionic g page About
<ion-header>
<ion-navbar>
<ion-title>About</ion-title>
</ion-navbar>
</ion-header>
<ion-content padding>
<p>Diese App wurde von Hendrik Lösch gebaut...</p>
<p> Alle Quellen finden sich <a href="https://github.com/HerrLoesch/MoviewMania">hier</a></p>
</ion-content>
79. Native Storage & Plugins
Why?
This plugin is created because of the non-persistent property of LocalStorage in the WebView of
Android and iOS. In iOS stored data from LocalStorage can be removed by the OS, when running out of
memory.
When to use the plugin
•Simple: Uniform and convenient way of organizing, storing, and accessing the data
•Fast: Less than 1 milisecond to save or retrieve an object (in general)
•Persistence: Save data over multiple sessions, i.e. holds the data till the application is
removed from the device
•Small data: Store small amounts of persistent data (less than a few hundred kilobytes)
• It is possible to store more than a few megabytes, but that's not the intended usage of
the plugin.
Quelle: https://github.com/TheCocoaProject/cordova-plugin-nativestorage
80. Plugin hinzufügen
npm install –g cordova
ionic plugin add cordova-plugin-nativestorage
ionic g provider store
Nur falls Cordova noch nicht installiert ist.
Fügt es nur der config.xml aber nicht
package.json hinzu!!!
"cordovaPlugins": [
"cordova-plugin-whitelist",
"cordova-plugin-console",
"cordova-plugin-statusbar",
"cordova-plugin-device",
"cordova-plugin-splashscreen",
"ionic-plugin-keyboard",
"cordova-plugin-nativestorage"
],
89. Probleme beim Erstellen eines neuen Projekts weil npm kein install ausführen kann.
Lösung: Aller neuste Node Version installieren und den Rechner neu starten.
90. Man kann selbst in neuen Projekten keine Ionicons sehen
(betrifft vor allem RC0)
^ Symbol entfernen oder auf Version 2.0.0 wechseln
Danach noch einmal npm install ausführen.
91. Es ist nicht möglich zu einer bestimmten Seite zu wechseln
Die Seite muss in declarations und(!) entryComponents der app.module.ts
eingetragen werden.