Speaker: Michel Morelli
Area: Development
Il talk verterà sulla creazione di una semplice app mobile che sfrutti il framework ionic per quello che riguarda l'accesso al mobile, il MVVM AngualarJS per quello che concerne il collegamento tra mobile e Drupal ed il modulo Service per quello che riguarda il reperimento delle informazioni lato Server.
5. Chi sono
Davide Michel Morelli
michel@ziobuddalabs.it
Programmatore PHP Senior, Drupal Senior e DBA MySQL
6. Chi sono
Davide Michel Morelli
michel@ziobuddalabs.it
Programmatore PHP Senior, Drupal Senior e DBA MySQL
Sviluppatore Web AngularJS, MongoDB (da poco) e NodeJS
7. Chi sono
Davide Michel Morelli
michel@ziobuddalabs.it
Programmatore PHP Senior, Drupal Senior e DBA MySQL
Sviluppatore Web AngularJS, MongoDB (da poco) e NodeJS
Sviluppatore Mobile su piattaforma HTML/CSS/JS
13. Drupal: Services
Si installa nel solito modo
Si deve creare quello che si chiama Rest point
14. Drupal: Services
Si installa nel solito modo
Si deve creare quello che si chiama Rest point
Maggiore diversificazione delle risorse
15. Drupal: Services
Si installa nel solito modo
Si deve creare quello che si chiama Rest point
Maggiore diversificazione delle risorse
All'interno della configurazione di services si possono dare i
permessi di accesso per i singoli servizi
17. Drupal: Services
Si installa nel solito modo
Si deve creare quello che si chiama Rest point
Maggiore diversificazione delle risorse
All'interno della configurazione di services si possono dare i permessi
di accesso per i singoli servizi
Attenzione: i permessi per accedere alla funzionalità del servizio
non sono i permessi di accesso di Drupal.
Vanno configurati anche questi
Altrimenti si avranno degli accessi negati senza capire il perché.
18. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
19. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
Drupal può rispondere in 3 modi diversi
20. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
Drupal può rispondere in 3 modi diversi
Creiamo la nostra funzione che risponde in JSON
21. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
Drupal può rispondere in 3 modi diversi
Creiamo la nostra funzione che risponde in JSON
Utilizziamo views_datasource che risponde in JSON
22. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
Drupal può rispondere in 3 modi diversi
Creiamo la nostra funzione che risponde in JSON
Utilizziamo views_datasource che risponde in JSON
Utilizziamo Services che consente i CRUD
23. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
Drupal può rispondere in 3 modi diversi
Creiamo la nostra funzione che risponde in JSON
Utilizziamo views_datasource che risponde in JSON
Utilizziamo Services che consente i CRUD
In Drupal Services i nodi si possono creare chiamando direttamente
il servizio /node
24. Drupal: Services
Per le applicazioni mobili ci servono le chiamate che ritornino del JSON
Perché è la soluzioni più pratica.
Drupal può rispondere in 3 modi diversi
Creiamo la nostra funzione che risponde in JSON
Utilizziamo views_datasource che risponde in JSON
Utilizziamo Services che consente i CRUD
In Drupal Services i nodi si possono creare chiamando direttamente
il servizio /node
La struttura deve essere come se lo stessi creando via PHP.
Title, Type, Body sono valori normali (nessuno nota l'errore?)
Un FIELD è invece nella struttura: { 'und' : [ { value: ILVALORE } ]}
che corrisponde a [LANGUAGE_NONE][0][value]
25. Drupal: Services
Attenzione nello sviluppo nella fase di debug:
Access-Control-Allow-Origin
(https://github.com/systemseed/services_accept_origin)
Plugin per Chrome:
“Allow-Control-Allow-Origin”
Questo problema c'è solo sui browser perché sugli smartphone l'accesso
avviene da file:// e non http://
Consiglio:
Testare su un device fisico è sempre meglio.
Si hanno le vere risposte delle performance e si può fare il debug
dell'html tramite chrome://inspect
28. AngularJS
E' un MVC
O meglio un MVVM perché c'è il doppio binding
29. AngularJS
E' un MVC
O meglio un MVVM perché c'è il doppio binding
Sviluppato da Google
30. AngularJS
E' un MVC
O meglio un MVVM perché c'è il doppio bindig
Sviluppato da Google
Permette di spostare la logica di funzionamento di un framework
direttamente sul frontend
31. AngularJS
E' un MVC
O meglio un MVVM perché c'è il doppio bindig
Sviluppato da Google
Permette di spostare la logica di funzionamento di un framework
direttamente sul frontend
Pensato per creare SAP: Singe Application Page
32. AngularJS
E' un MVC
O meglio un MVVM perché c'è il doppio bindig
Sviluppato da Google
Permette di spostare la logica di funzionamento di un framework
direttamente sul frontend
Pensato per creare SAP: Singe Application Page
Ma lo si può usare in tanti modi
35. IonicFramework
All'inizio c'erano le applicazioni che venivano create con il linguaggio
dello smartphone
Poi si è pensato di utilizzare il web per creare delle piccole pagine a
modo di applicazione ed è stato inventato jQueryMobile
36. IonicFramework
All'inizio c'erano le applicazioni che venivano create con il linguaggio
dello smartphone
Poi si è pensato di utilizzare il web per creare delle piccole pagine a
modo di applicazione ed è stato inventato jQueryMobile
Poi c'è stato Phonegap (diventato poi cordova, ma rimasto anche
Phonegap) che ha permesso di creare delle specie di applicazioni
native che sfruttano il browser
37. IonicFramework
All'inizio c'erano le applicazioni che venivano create con il linguaggio
dello smartphone
Poi si è pensato di utilizzare il web per creare delle piccole pagine a
modo di applicazione ed è stato inventato jQueryMobile
Poi c'è stato Phonegap (diventato poi cordova, ma rimasto anche
Phonegap) che ha permesso di creare delle specie di applicazioni
native che sfruttano il browser
Phonegap/Cordova fornisce solo l'accesso alla risorsa dello smartphone
all'interno del browser
Tastiera
Vibrazione
Fotocamera
Filesystem
Altro...
39. IonicFramework
JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere
visualizzato e poi nascosto
Angular ha il concetto di “vista” che può essere riempita a seconda di
quello che si vuole visualizzare
40. IonicFramework
JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere
visualizzato e poi nascosto
Angular ha il concetto di “vista” che puo' essere riempita a secondo di
quello che si vuole visualizzare
Sullo smartphone (meno memoria, meno potenza di calcolo) è molto
meglio visualizzare poco alla volta
41. IonicFramework
JqueryMobile ha pero' il concetto di unica pagina dove tutto deve essere
visualizzato e poi nascosto
Angular ha il concetto di “vista” che puo' essere riempita a secondo di
quello che si vuole visualizzare
Sullo smartphone (meno memoria, meno potenza di calcolo) è molto
meglio visualizzare poco alla volta
Quindi come unire mobile, user interface e applicazioni native ?
44. IonicFramework
IonicFramework prende Cordova e lo unisce ad Angular ampliandoli
Accesso al dispositivo (cordova)
Gestione della visualizzazione, del reperimento dei dati (angularjs)
45. IonicFramework
IonicFramework prende Cordova e lo unisce ad Angular ampliandoli
Accesso al dispositivo (cordova)
Gestione della visualizzazione, del reperimento dei dati (angularjs)
Attività normali dello smartphone rese disponibili
46. IonicFramework
Via JS
Slide menu
Tab
Swipe
Routing per le pagine interne
Finestre modali
Finestre di loading (spinner)
48. IonicFramework
Come fare le chiamate con Ionic, o meglio via AngularJS:
3 alternative praticabili
$http
$resource
Restangular
Sono messe in ordine di “livello di programmazione”.
Dal più basso al più alto.
49. IonicFramework
Per questo talk ho usato Restangular, anche se ci sono cose che non mi
piacciono:
Il risultato della chiamata viene restituito come oggetto
Restangular
Ma quello che abbiamo richiesto è messo allo stesso livello delle
funzioni native.
Quindi se riceviamo un array di informazioni non possiamo
utilizzare angular.forEach() perché andremmo a prendere
anche le funzioni native.
50. IonicFramework
Per questo talk ho usato Restangular, anche se ci sono cose che non mi
piacciono:
Il risultato della chiamata viene restituito come oggetto Restangular
Ma quello che abbiamo richiesto è messo allo stesso livello delle
funzioni native.
Quindi se riceviamo un array di informazioni non possiamo
utilizzare angular.forEach() perché andremmo a prendere
anche le funzioni native.
Per usarlo con drupal è necessario modificarne il funzionamento
(tramite apposita funzione addResponseInterceptor, nessuna modifica al
codice di Restangular) perché Services ritorna una serie di oggetti,
mentre Restangular vuole un elemento solo oppure un array.
51. IonicFramework
Per questo talk ho usato Restangular, anche se ci sono cose che non mi
piacciono:
Il risultato della chiamata viene restituito come oggetto Restangular
Ma quello che abbiamo richiesto è messo allo stesso livello delle
funzioni native.
Quindi se riceviamo un array di informazioni non possiamo
utilizzare angular.forEach() perché andremmo a prendere
anche le funzioni native.
Per usarlo con drupal è necessario modificarne il funzionamento (tramite
apposita funzione addResponseInterceptor, nessuna modifica al codice di
Restangular) perché Services ritorna una serie di oggetti, mentre Restangular
vuole un elemento solo oppure un array.
Per un altro progetto ho usato $http. Meno funzioni evolute, ma più
usabile
52. IonicFramework
Vediamo come IonicFramework gestisce le varie “view”.
Prima di tutto il file principale: INDEX.HTML
54. IonicFramework
<!-- cordova script (this will be a 404 during development) -->
<script src="cordova.js"></script>
<!-- build:js scripts/scripts.js -->
<script src="scripts/common/angular-cookie.min.js"></script>
<script src="scripts/common/underscore-min.js"></script>
<script src="scripts/common/restangular.min.js"></script>
<script src="scripts/config.js"></script>
<script src="scripts/app.js"></script>
<script src="scripts/controllers.js"></script>
<script src="scripts/common/restfulServices.js"></script>
<script src="scripts/common/sharedService.js"></script>
<script src="scripts/user/loginCtrl.js"></script>
<script src="lib/sweetalert/lib/sweet-alert.min.js"></script>
<link rel="stylesheet" href="lib/sweetalert/lib/sweet-alert.css">
<script src="scripts/posts/picture.js"></script>
<script src="scripts/posts/singlePostCtrl.js"></script>
<script src="scripts/homeCtrl.js"></script>
<!-- endbuild -->
</body>
</html>
L'unico motivo per modificare questo file è per inserire i vari SCRIPT dei
nostri controller
55. IonicFramework
Ed il file che gestisce le view: app.js
'use strict';
// Ionic Starter App, v0.9.20
// angular.module is a global place for creating, registering and retrieving Angular modules
// 'starter' is the name of this angular module example (also set in a <body> attribute in index.html)
// the 2nd parameter is an array of 'requires'
angular.module('Utrend', ['ionic', 'config', 'Utrend.controllers','restangular','ipCookie'])
.run(function($ionicPlatform) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
if(window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if(window.StatusBar) {
// org.apache.cordova.statusbar required
StatusBar.styleDefault();
}
});
})
57. IonicFramework
Ed il file che gestisce le view: app.js
.state('app.browse', {
url: '/browse',
views: {
'menuContent' :{
templateUrl: 'templates/browse.html',
controller: 'singlePostCtrl'
}
}
})
.state('app.getPicture', {
url: '/getpicture',
views: {
'menuContent' :{
templateUrl: 'templates/getPicture.html',
controller: 'pictureCtrl'
}
}
});
58. IonicFramework
Ed il file che gestisce le view: app.js
// if none of the above states are matched, use this as the fallback
$urlRouterProvider.otherwise('/app/home');
$compileProvider.imgSrcSanitizationWhitelist(/^s*(https?|ftp|mailto|file|tel):/);
RestangularProvider.setBaseUrl('http://MYDOMAIN/');
RestangularProvider.setResponseExtractor(function(response) {
var newResponse = response;
newResponse.originalElement = angular.copy(response);
return newResponse;
});
});
59. Drupal Service + IonicFramework
Per collegarci a Drupal abbiamo detto che utilizzeremo Services
60. Drupal Service + IonicFramework
Per collegarci a Drupal abbiamo detto che utilizzeremo Services
Ma dobbiamo prestare attenzione ad una cosa molto importante:
il token CSRF
61. Drupal Service + IonicFramework
Per collegarci a Drupal abbiamo detto che utilizzeremo Services
Ma dobbiamo prestare attenzione ad una cosa molto importante:
Il token CSRF
E' stato aggiunto dalla versione 3.5 del modulo services
62. Drupal Service + IonicFramework
Per collegarci a Drupal abbiamo detto che utilizzeremo Services
Ma dobbiamo prestare attenzione ad una cosa molto importante:
Il token CSRF
E' stato aggiunto dalla versione 3.5 del modulo services
Lega a doppio mandato la sessione attuale con quella registrata sul server
Per fare qualsiasi operazione che non sia un GET è richiesto questo
TOKEN negli header della richiesta
63. Drupal Service + IonicFramework
Per collegarci a Drupal abbiamo detto che utilizzeremo Services
Ma dobbiamo prestare attenzione ad una cosa molto importante:
Il token CSRF
E' stato aggiunto dalla versione 3.5 del modulo services
Lega a doppio mandato la sessione attuale con quella registrata sul server
Per fare qualsiasi operazione che non sia un GET è richiesto questo
TOKEN negli header della richiesta
Per rendere il codice scritto più gestibile e leggibile è consigliabile
creare un service di angular che gestisca per noi le connessioni
64. Drupal Service + IonicFramework
(function () {
angular.module('MyM').service('restfulService',['ipCookie','Restangular','$q',restfulService]);
var tokenVar = '';
function restfulService(ipCookie,Restangular,$q) {
//Qui le chiamate REST
return {
//Setta la directory di partenza del service rest. In questo modo non devo sempre definirlo
restfulBase : function() {
return Restangular.oneUrl('rest','http://MioDominio/rest');
},
}
})();
65. Drupal Service + IonicFramework
Prendiamo il token
getToken : function(reset) {
if (tokenVar != '' && !reset) {
var deferred = $q.defer();
deferred.resolve(tokenVar);
return deferred.promise
}
return
Restangular.oneUrl('services/session/token','http://MIODOMINIO/services/session/token').get().then(function
(token) {
tokenVar = token;
return token;
});
},
Notate come non abbia utilizzato restfulBase ma solamente per una
questione di demo
66. Drupal Service + IonicFramework
E' facile creare una app che permetta di gestire gli utenti collegati e
quelli non collegati (anonimi)
67. Drupal Service + IonicFramework
E' facile creare una app che permetta di gestire gli utenti collegati e
quelli non collegati (anonimi)
Per farlo utilizzeremo AngularJS e il suo ng-if modificando il file di
template del menù slide
70. Drupal Service + IonicFramework
Vediamo il controller per il login (notate cosa usa)
/**
* Created by ziobudda on 05/11/14.
*/
(function () {
angular.module('Utrend').controller('loginCtrl',
['$scope','$ionicModal','$state','sharedService','restfulService','$rootScope', loginCtrl]);
function loginCtrl($scope, $ionicModal,$state,sharedService,restfulService,$rootScope) {
$scope.error_message = '';
sharedService.getToken();
// Form data for the login modal
$scope.loginData = {};
// Create the login modal that we will use later
$ionicModal.fromTemplateUrl('templates/login.html', {
scope: $scope
}).then(function(modal) {
$scope.modal = modal;
});
// Triggered in the login modal to close it
$scope.closeLogin = function() {
$scope.modal.hide();
},
71. Drupal Service + IonicFramework
// Open the login modal
$scope.login = function() {
$scope.modal.show();
};
// Perform the login action when the user submits the login form
$scope.doLogin = function() {
console.log('Doing login22', $scope.loginData);
restfulService.login($scope.loginData)
.then(function(result) {
$rootScope.$broadcast("login",{user: result.user});
restfulService.getToken(true).then(function(result) {
$scope.closeLogin();
swal({title: "Login OK", text: "Now you are a loggedin user!", type: "success"});
$state.go('app.browse')
})
}, function (result) {
$scope.error_message = result.data[0];
});
}
72. Drupal Service + IonicFramework
$scope.logout = function () {
restfulService.logout()
.then(function(result) {
sharedService.user = {};
sharedService.user.uid = 0;
swal({title: "Logout OK", text: "Now you are a logged out user!", type: "success"});
$rootScope.$broadcast("logout");
$state.go("app.home");
});
}
};
})();
73. Drupal Service + IonicFramework
In questo controller abbiamo:
Le finestre modali (per chiedere login e password)
74. Drupal Service + IonicFramework
In questo controller abbiamo:
Le finestre modali (per chiedere login e password)
La gestione automatica del menù slide fatto tramite una semplice
valorizzazione di sharedService.user
75. Drupal Service + IonicFramework
E per visualizzare dei dati presi via GET ? Nella nostra app di prova sono
delle immagini
Il controller è puro AngularJS
76. Drupal Service + IonicFramework
E per visualizzare dei dati presi via GET ? Nella nostra app di prova sono
delle immagini
Il controller è puro AngularJS
Al div principale sono state definite le funzioni per gestire
swipe a sinistra
swipe a destra
<div on-swipe-left="onSwipeLeft()" on-swipe-right="onSwipeRight()" >
E' IonicFramework che rende facilmente disponibile il service
$swipe di AngularJS
https://docs.angularjs.org/api/ngTouch/service/$swipe
81. Riassumendo
Per creare applicazioni mobili che sfruttano l'html5:
AngularJS
IonicFramework (per velocizzare lo sviluppo)
Un servizio remoto che permetta di ricevere le informazioni da
visualizzare in formato JSON
83. Link utili
AngularJS: https://angularjs.org/
IonicFramework: http://ionicframework.com/
IonicFramework Generator: https://github.com/diegonetto/generator-ionic
La mia rivista flipboard dedicata ad angularJS e gli altri JS
https://flipboard.com/section/angularjs%2C-nodejs-e-gli-altri-js-bTb8rt
Icone per le app: http://ionicons.com/
Usare FontAwesome (Bootstrap):
http://blog.nraboy.com/2014/10/
use-font-awesome-glyph-icons-ionicframework/