New Media Design & Development III - Ionic Framework Academiejaar 2014-2015, Arteveldehogeschool ©2014 Olivier Parent
[TOC]
Ionic is een framework om Native Hybrid Mobile Apps te ontwikkelen met behulp van HTML, CSS en JavaScript.
Ionic gebruikt Apache Cordova om de app te verpakken tot een Native App.
Cordova is het opensource project waarop Adobe PhoneGap gebaseerd is. Nadat PhoneGap door Adobe overgenomen werd, doneerde Adobe de broncode aan The Apache Software Foundation.
Ionic past Syntactically Awesome Style Sheets toe, een CSS-preprocessor die de Sass-taal omzet naar gewone CSS. Het is een van de oudste CSS-preprocesors en ook de populairste. Andere bekende CSS-preprocessors zijn bijvoorbeeld LESS en Stylus, maar er zijn er nog vele andere.
Sass is ontstaan als aanvulling op Haml, een taal om Sjablonen voor HTML-documenten te maken. In eerste instantie gebruikte Sass een zeer compacte syntaxis die leek op die van Haml en hadden de bestanden de extensie .sass
.
Sinds Sass versie 3 werd, deels onder druk van de community en van nieuwe concurrenten, een nieuwe syntaxis geïntroduceerd: SCSS (Sassy CSS). Deze nieuwe syntaxis is een uitbreiding van CSS, waardoor ook gewone CSS in SCSS gebruikt kan worden. Bestanden die geschreven zijn in deze nieuwe syntaxis hebben .scss
als extensie.
Ionic is gebaseerd op Google AngularJS, het meest populaire JavaScript MV*-framework van dit moment. Op korte tijd heeft het de gevestigde waarden als Backbone.js en Ember.js van de troon gestoten.
AngularJS is een MVW-framework. De meeste frameworks houden vast aan één Design Pattern:
- MVC (Model-View-Controller)
- MVVM (Model-View-ViewModel)
- MVP (Model-View-Presenter)
Angular geeft de ontwikkelaar de vrijheid om Whatever works for you te gebruiken. In de praktijk meestal iets tussen MVC en MVVM in.
AngularJS heeft ook een Dart-tegenganger: AngularDart.
Dart is een nieuwe taal van Google die de gebreken van JavaScript moet verhelpen. Omdat andere vendors niet snel geneigd zijn om ook Dart te gebruiken, omdat ze zelf een eigen vervanger voor JavaScript hebben (Microsoft heeft bijv. TypeScript en Mozilla werkt mee aan ECMAScript 6, beter bekend onder de naam "JavaScript 2.0"), kan Dart omgezet worden naar JavaScript.
We moeten 2 packages globaal installeren:
Deze packages installeer je als volgt:
$ npm install -g cordova ionic
$ cordova -v
$ ionic -v
Met deze CLI-utility's kan je een Ionic project maken:
$ ionic start <mapnaam> <projectsjabloon>
Proxy Server In tegenstelling tot
$ export http_proxy=http://proxy.arteveldehs.be:8080 $ PROXY=$http_proxy ionic start <mapnaam> <projectsjabloon>
Bijvoorbeeld:
$ ionic start app_tabs tabs
OPGELET: gebruik nooit een slash in de mapnaam!
Er zijn vier basissjablonen.
Sjabloon | Omschrijving |
---|---|
blank |
Leeg project. |
maps |
Project met een kaart. |
sidemenu |
Project met een sidemenu. |
tabs |
Project met een tabnavigatie. |
Je kan een ingebouwde server starten met de Ionic CLI-utiliy om je App te testen in een browser. Hiermee kan je dan wel geen mobile features simuleren.
Ga naar de projectmap en start de server:
$ ionic serve
Dit is eigenlijk een uitbreiding op
$ cordova serve
Zie ook:
Een Cordova App kan voor heel veel verschillende platformen ontwikkeld worden. Ionic neem deze over.
Elk platform moet afzonderlijk in je project geïnstalleerd worden.
Ga naar de projectmap en installeer het Firefox OS Platform:
$ ionic platform add firefoxos
Daarna moet je de app voorbereiden
$ cordova prepare
Dit zal alle plaformen voorbereiden, maar je kan ook het platform specificeren:
$ cordova prepare firefoxos
Emulators installeren en configureren is vrij omslachtig. Daarenboven zijn ze vaak traag en hebben ze veel RAM-geheugen nodig. Vooral de Android-emulator werkt ontzettend traag (zelfs met x86-emulatie en Intel hardwareacceleratie). De iOS-emulator is dan weer enkel op Mac OS X beschikbaar.
De Firefox OS Simulator (een onderdeel van Firefox WebIDE)werkt bijna net zo snel als de Firefox browser waarop het gebaseerd is. Deze simulator is standaard geinstalleerd op Firefox Developer Edition.
Benodigdheden:
Open Firefox Developer Edition en open WebIDE
Extra → Webontwikkelaar → WebIDE
Installeer een simulator voor Firefox OS.
Runtime selecteren → Simulator installeren
Start een simulator, bijv. Firefox OS 2.0
Runtime selecteren → Firefox OS 2.0
Open de app in Firefox WebIDE als Verpakte app (Packaged app).
App openen → Verpakte app openen…
Ga naar de map van de app en kies vervolgens de submap platforms/firefoxos/www/
en klik op de button Open.
- Mac OS X
- Xcode en Xcode Command Line Developer Tools
- Apple iOS Developer Program Account om naar een iOS-toestel te deployen.
ios-sim
om naar een iOS Simulator te deployen.ios-deploy
om naar een iOS-toestel te deployen.
Installeer ios-deploy
en ios-sim
:
$ npm install -g ios-deploy
$ npm install -g ios-sim
In de projectmap voegen we het iOS-platform toe:
$ ionic platform add ios
Dit is gebaseerd op:
$ cordova platform add ios
$ ionic emulate ios
Dit is gebaseerd op:
$ cordova emulate ios
Open het Xcode-project (*.xcodeproj
) dat in de map platforms/ios/
staat en pas de Build Settings aan zodat Code Signing Identity overeenkomt met je iOS Developer Program Account.
Deploy daarna de app.
$ ionic run ios
Dit is gebaseerd op:
$ cordova run ios
Zie ook:
Een nieuwe project aanmaken in de map app/
:
$ ionic start app blank
$ cd app/
Mappenstructuur
nmdad-iii.arteveldehogeschool.be/ └── app/ └── www/ ├── css/ | └── style.css ├── img/ | └── ionic.png ├── js/ | └── app.js ├── lib/ | └── ionic/ └── index.html
Het project bekijken in een browser:
$ ionic serve localhost
Platformen kan je achteraf nog installeren.
Mappenstructuur
nmdad-iii.arteveldehogeschool.be/ └── app/ └── www/ ├── js/ | └── app.js └── index.html
In AngularJS wordt een app opgebouwd in modules. Dit zijn eigenlijk namespaces.
// Setter die de module maakt
angular.module('mijn-module', []);
// Getter om de module op te halen
angular.module('mijn-module');
Een module heeft een aantal blokken:
Code | Wat is het? |
---|---|
.config() |
Configuration Block |
.run() |
Run Block |
|
Code die bij het opstarten van de app uitgevoerd moet worden.
Object | Scope |
---|---|
$rootScope |
App |
$scope |
Controller, Directive, DOM Element |
$scope
neemt automatisch de properties over van de $scope
van de parent (bijv. parentcontroller) over.
Controllers moeten een naam hebben die eindigt op Controller
(Ctrl
wordt ook vaak gebruikt maar is niet aangeraden).
In js/app.js
:
(function () { 'use strict';
angular.module('mijn-app', []);
})();
In js/controllers/MijnController.js
:
(function () { 'use strict';
var app = angular.module('mijn-app');
app.controller('MijnController', ['$scope', function ($scope) {
$scope.hello = 'Hallo Wereld!';
}]);
})();
In de js/App.js
:
angular.module('mijn-app', []);
In de index.html
:
<script src="js/controllers/MijnController.js"></script>
<h1 ng-controller="MijnController">{{ hello }}</h1>
Zie ook:
Directives zijn JavaScript-objecten die je gebruik om de DOM te manipuleren. In de HTML plaats je markeringen waaraan de HTML Compiler de Directives koppelt tijdens de Compile-fase.
Je kan Directives zelf maken, of je gebruikt de standaard ingebouwde Directives van AngularJS of Ionic.
Markering als: | restrict: |
HTML-voorbeeld voor mijnDirective |
---|---|---|
Element | E |
<mijn-directive> |
Attribuut | A |
<div mijn-directive></div> |
Klasse | C |
<div class="mijn-directive"></div> |
Commentaar | M |
<!-- directive: mijn-directive --> |
js/directives/arteveldeHello.js
:
(function () { 'use strict';
var AppDirectives = angular.module('artevelde.directives');
AppDirectives
.directive('arteveldeHello', function () {
var i = 0;
return {
restrict: 'EACM', // Voor gebruik op Element, Attribute, Class en Comment
link: function () {
console.log('Hello from Directive arteveldeHello to MMP proDEV (' + ++i + ')!');
},
};
})
;
})();
In de index.html
:
<artevelde-hello>
<span artevelde-hello></span>
<span class="artevelde-hello"></span>
<!-- directive: artevelde-hello -->
Zie ook:
Services zijn Singletons die je kan aanspreken doorheen de applicatie. In tegenstelling tot Controllers, blijven Services de hele lifecycle van de applicatie bestaan.
Een singleton is een object die maar 1 keer geïnstantieerd wordt, zodat je telkens hetzelfde object gebruikt. Je kan er dus ook tijdelijk gegevens in bewaren.
Enkele voorbeelden van standaard Services in AngularJS:
$http
$location
$log
$rootScope
$window
- …
…
Zie ook:
De communicatie met een HTTP-server gebeurt in AngularJS via de Service $http
. Deze Service is eigenlijk een wrapper is voor het XMLHttpRequest
-object en JSON-P.
Methode | HTTP-methode |
---|---|
.head(url) |
HEAD |
.get(url) |
GET |
.jsonp(url) |
GET |
.post(url, data) |
POST |
.put(url, data) |
PUT |
.delete(url) |
DELETE |
Als resultaat krijg je een promise terug.
Promise | Uitgevoerd als? |
---|---|
.success(successCallback) |
Als de request succesvol was. |
.error(errorCallback) |
Als de request een fout teruggaf. |
Een moderne User Agent (bijv. browser of app) heeft een Same-Origin Security Policy. Dit wil zeggen dat de bronnen (resources), zoals bijvoorbeeld JavaScript-bestanden of gegevens, allen dezelfde oorsprong (protocol, domein en poort) moeten hebben, zoniet worden ze geweigerd.
Eén manier om deze beperking te omzeilen is werken met JSON-P, maar daar kan je enkel gegevens mee inlezen. Een andere manier is werken met een proxyscript op hetzelfde domein als de User Agent, maar dit is niet altijd mogelijk
De betere manier is CORS inschakelen. CORS is een W3C Recommendation die door moderne User Agents geïmplementeerd is.
Ga naar de projectmap en open www/js/App.js
en laat zet useXDomain
('Use Cross Domain') op true
en verwijder in de Request Header X-Requested-With
:
.config(['$httpProvider', function ($httpProvider) {
// Enable CORS (Cross-Origin Resource Sharing)
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])
AngularJS zal alle niet erkende protocollen prefixen met unsafe:
. In een Firefox OS zal het protocol app:
gebruikt worden. De Firefox OS simulator zal de app afsluiten als dit onbekende protocol (unsafe:app://
) gebruikt wordt.
De erkenning gebeurt op basis van deze Reguliere Expressie in src/ng/sanitizeUri.js
:
- a[href]:
/^\s*(https?|ftp|mailto|tel|file):/
- img:
/^\s*((https?|ftp|file):|data:image\/)/
Zie ook:
Ga naar de projectmap en open www/js/App.js
en voeg je app
als protcol toe:
.config(['$compileProvider', function($compileProvider) {
$compileProvider
.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|tel|file|app):/)
.imgSrcSanitizationWhitelist(/^\s*((https?|ftp|file|app):|data:image\/)/);
}])
Daarna moet het aangepast script naar elk platform gekopieerd worden met:
$ cordova prepare