alloy, un framework MVC pour Appcelerator Titanium mobile
This is a talk given during the 2nd meeting of the Paris Titanium User Group. Alloy is the new Open Source MVC framework published by Appcelerator, which enforces an efficient and structured way of easily building mobile cross-browser applications.
Titanium n°2 | Xavier Lacot | Septembre 2012 Qui suis-je ? Xavier Lacot ▪ Expert Web et Mobile chez JoliCode – http://jolicode.com ▪ Contributeur à plusieurs projets Open Source ▪ En PHP, notamment Symfony ▪ Développeur Titanium depuis 2009 ▪ Conférencier à CodeStrong ▪ Expert frameworks Web ▪ Plusieurs conférences – Symfony Live, Forum PHP, Symfony Day, etc. ▪ Président de l'Association Française des Utilisateurs de PHP (afup.org) ▪ http://twitter.com/xavierlacot
Titanium n°2 | Xavier Lacot | Septembre 2012 Qu'est-ce que Titanium ? « Titanium is an open source framework for building native desktop and mobile applications using open web technologies (HTML, CSS, and JavaScript) »
Titanium n°2 | Xavier Lacot | Septembre 2012 La productivité a ses limites... ▪ Quelques limitations néanmoins : ▪ Pour le développeur, Titanium est une plateforme ▪ Pas un framework au sens RAD / MVC ▪ UI écrite en JS = aïe ▪ Plateforme géniale mais : ▪ Peu contraignante ▪ Bonnes pratiques : selon le développeur ▪ De nombreux frameworks pseudo-MVC ▪ Manque de standardisation des savoir-faire ▪ Contributions hétérogènes
Titanium n°2 | Xavier Lacot | Septembre 2012 Alloy ▪ Alloy ▪ Open Source, mené par Appcelerator ▪ Apparu début 2012 (première béta en juin) ▪ Utilise des composants ouverts (projets tiers) ▪ S'appuie sur node.js, disponible par npm ▪ Déjà bien documenté ▪ GitHub : 250 stars, 49 forks ▪ Test : http://projects.appcelerator.com/alloy/docs/Alloy-bootstrap/index.html
Titanium n°2 | Xavier Lacot | Septembre 2012 Objectifs ▪ Productivité ▪ Développer plus rapidement ; ▪ Construire des librairies réutilisables ; ▪ Générer du code ▪ Pousser les bonnes pratiques ▪ Fini les variables globales et les Ti.include() de 200 fichiers au bootstrap de vos applications ! ▪ Améliorer la maintenabilité ▪ Aujourd'hui : 1 développeur = 1 style de développement ▪ Objectif : architectures uniformes = réversibilité facilitée
Titanium n°2 | Xavier Lacot | Septembre 2012 Installer alloy ▪ Pré-requis pour jouer : ▪ node.js 0.6.3 ou plus ▪ Titanium SDK + Studio >= 2.1 ▪ OSX 10.6 (pas windows ou Linux pour le moment) ▪ Installation : $ sudo npm install alloy -g
Titanium n°2 | Xavier Lacot | Septembre 2012 Outillage ▪ Un outil en ligne de commande : ▪ new : initialise un projet alloy ▪ compile : compile le projet pour cible « webapp » ▪ run : lance l'application ▪ generate : génère du code (contrôleur / modèle)
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy dossier de code lié à alloy Dossiers et fichiers habituels d'un projet Titanium app/ build/ i18n/ modules/ plugins/ Resources/ manifest tiapp.xml Ne codez plus dans Resources !
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Les assets (images, sons, etc.) de votre projet. Déployé dans Resources/ à la compilation app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Les librairies CommonJS : ▪ Vos librairies métier ▪ Des libs externes (lib/vendor) Dossier à créer à la main Chargement par : require('library') app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Les classes de migration de vos modèles de données. Dossier à créer à la main app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Les classes du modèle de données. app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Les vues de l'application : des templates au format XML Plus besoin de Ti.UI.create* app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Les widgets propres à votre application (ie., non fournis par alloy). Les widgets sont des composants à assembler pour créer l'application. Dossier à créer à la main app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Architecture d'un projet alloy Fichier type makefile, pour définir des opérations pre- et post- compilation : ▪ Changer la configuration ▪ Logger des informations ▪ Déployer sur un serveur ▪ etc. app/ assets/ controllers/ lib/ migrations/ models/ styles/ views/ widgets/ alloy.jmk README config.json
Titanium n°2 | Xavier Lacot | Septembre 2012 Principe de fonctionnement Code écrit pour alloy Code Titanium « traditionnel » run / compile En résumé, alloy est un compilateur de code structuré, réutilisable et moderne vers du code « Titanium » respectant les bonnes pratiques. alloy ne remplace pas Titanium, il le complète.
Titanium n°2 | Xavier Lacot | Septembre 2012 La gestion des vues ▪ Les vues sont des fichiers XML ▪ Au moins une vue (le premier « écran ») : index.xml ▪ Les vues ne définissent pas l'apparence de l'application mais seulement son organisation ▪ Les styles .tss permettent de styler les vues (analogie à HTML et CSS)
Titanium n°2 | Xavier Lacot | Septembre 2012 La gestion des vues ▪ Exemple de vue principale : <Alloy> <Window class="container"> <Label id="label" onClick="doClick">Hello, World</Label> </Window> </Alloy> <Alloy> : conteneur de l'application <Window> : Préfixé par Ti.UI. Attribut ns="..."
Titanium n°2 | Xavier Lacot | Septembre 2012 La gestion des vues ▪ Exemple de vue principale : <Alloy> <Window class="container"> <Label id="label" onClick="doClick">Hello, World</Label> </Window> </Alloy> Support de classes et d'identifiants Possible de gérer des évènements
Titanium n°2 | Xavier Lacot | Septembre 2012 Les contrôleurs, un peu d'activité en vue... ▪ Même principe pour les contrôleurs : ▪ nom_de_vue.xml ↔ nom_de_vue.js <View id="a"> <Button id="b">Hello</Button> <Label id="t" onClick="doClick">Michel</Label> </View> app/views/toto.xml $.a.backgroundColor = 'blue'; $.b.addEventListener('click', function(e){ $.t.text = 'Gérard'; }); function doClick(e) { $.t.color = 'green'; } app/controllers/toto.js Ajout de comportement par écouteur d'évènement Ajout de comportement depuis la vue
Titanium n°2 | Xavier Lacot | Septembre 2012 Gestion des données ▪ Vos applications manipulent des données ▪ Ces données sont stockées par le biais de Modèles ▪ alloy gère les modèles en s'appuyant sur : ▪ backbone ▪ des adaptateurs pour le stockage des données Application (contrôleur) Modèles (étendent Backbone.Model) Adapteurs fournis par alloy storage
Titanium n°2 | Xavier Lacot | Septembre 2012 $ alloy generate model photo sql name:string url:string is_enabled:boolean .__ .__ _____ | | | | ____ ___.__. $ alloy generate model photo sql name:string url:string is_enabled:boolean Commande de création de modèle Nom du modèle à créer Type d'adaptateur à employer Liste des champs (sauf pour localStorage) ▪ Génère : ▪ La définition du modèle dans app/models/photo.js ▪ Une migration dans app/migrations
Titanium n°2 | Xavier Lacot | Septembre 2012 Utilisation d'un modèle de données (1/2) ▪ Une fois le modèle défini, on peut l'utiliser immédiatement dans nos contrôleurs : var photos = Alloy.createCollection('Photos'); // create a new Photo var photo = Alloy.createModel('Photo', { name:"HOTLINE", url:"http://picmybox.fr/media/large/photos/hotline.jpg", is_enabled: true }); // add it to the photos collection photos.add(photo);
Titanium n°2 | Xavier Lacot | Septembre 2012 Utilisation d'un modèle de données (2/2) ▪ Les modèles étendent Backbone.Model ! ▪ cf. http://backbonejs.org/ // create and fetch the collect var photos = Alloy.createCollection('Photos'); photos.fetch(); // retrieve only the enabled photos var enabled_photos = photos.where({is_enabled: true}); // update a view element when photos are fetched from the storage photos.on("fetch", function() { $.table.updateContent(photos); });
Titanium n°2 | Xavier Lacot | Septembre 2012 Les widgets, un soupçon de réutilisabilité ▪ Un widget est un module embarquant sa propre logique MVC ▪ Un widget est un package réutilisable, autonome, qui peut être importé dans toute application ▪ Un widget peut fournir des vues, ou simplement des fonctionnalités
Titanium n°2 | Xavier Lacot | Septembre 2012 Les widgets, un soupçon de réutilisabilité ▪ Toute partie « générique » d'une application devrait être développée sous la forme d'un widget ▪ Datepicker ▪ Formulaire de connexion Oauth ▪ etc. ▪ Créer un widget est simple : $ alloy generate widget com.picmybox.hellobutton .__ .__ _____ | | | | ____ ___.__. \__ \ | | | | / _ < | | / __ \| |_| |_( <_> )___ | (____ /____/____/\____// ____| \/ \/ Alloy by Appcelerator. The MVC app framework for Titanium. [INFO] Generated widget named com.picmybox.hellobutton
Titanium n°2 | Xavier Lacot | Septembre 2012 Structure d'un Widget ▪ Le code est généré dans app/widgets/XXX ▪ Un widget se présente comme une application à part entière ▪ Vue ▪ Contrôleur ▪ Modèles ▪ Librairies ▪ widget.json décrit le widget
Titanium n°2 | Xavier Lacot | Septembre 2012 Utilisation d'un Widget ▪ Emploi d'un widget dans une vue : ▪ Un widget peut embarquer sa propre logique ▪ On peut la surcharger localement dans l'application ▪ S'il y en a, les assets seront copiés dans Resource/ <Alloy> <Window id="coucou"> <Require type="widget" src="com.picmybow.helloButton" id="poney"/> </Window> </Alloy>
Titanium n°2 | Xavier Lacot | Septembre 2012 Au sujet des widgets... ▪ Appcelerator souhaite faciliter la distribution de widgets – dans la Marketplace ? ▪ Pour l'instant, pas de packaging sous forme d'archive (mais envisagé) ▪ Un widget peut exposer une API publique vers l'application : // widget.js controller file exports.doSomething = function() { alert('Coucou poney'); } // application controller $.foo.doSomething(); Mot-clé exports : définition d'une API publique (bisous CommonJS) Appel de la méthode par le biais du nom du Widget
Titanium n°2 | Xavier Lacot | Septembre 2012 Débugger ses applications ▪ Le debug (comme la compilation / distribution) se fait directement depuis Titanium Studio, comme d'habitude ▪ La précompilation alloy → Titanium peut détecter des problèmes triviaux. Par exemple : [INFO] [index.xml] view processing... [INFO] style: "index.tss" [INFO] view: "index.xml" [ERROR] Error parsing XML document [ERROR] end tag name: Window is not match the current start tagName:Windo [ERROR] Alloy compile failed
Titanium n°2 | Xavier Lacot | Septembre 2012 En guise de conclusion... alloy : ▪ structure fortement le développement avec Titanium ; ▪ apporte une réponse à ceux qui ne savent pas comment (bien) démarrer leur projet ; ▪ facilite l'utilisation de librairies de qualité. alloy est encore en pre-release ▪ Mais ça marche déjà bien ▪ Si vous aimez jouer, foncez ou au moins testez-le !