Flex et composants mobile (AIR pour Android – iOS) – Mon approche
Dans mon dernier billet, je faisais une critique des composants adaptés aux mobiles prévus pour la prochaine release du Flex SDK: Flex 4.5 SDK "Hero". Alors certains vont dire que ce n'est pas très juste de critiquer un produit qui n'est pas encore sorti de manière définitive.
Mais le problème se situe plutôt dans la philosophie de ces composants qui est décrite en détail dans les spécifications disponibles sur le site d'Adobe. Pas besoin donc de tester car ces composants vont respecter les spécifications, on sait déjà à quoi s'attendre.
Bref, l'approche de Hero ne me convenant pas, j'ai décidé de créer mon propre framework de composants adaptés aux mobiles, en Flex 3. Dans ce billet (qui sera découpé en plusieurs billets), je vais expliquer la démarche que j'ai suivi, aussi bien au niveau de la réflexion que de la réalisation.
Code en téléchargement?
Quand on lit les forums de la pre-release d'AIR pour Android ou de celui sur le Packager For iPhone, on se rend compte que de nombreuses personnes cherchent un framework avec des composants adaptés aux environnements mobiles. La réponse que donnent les employés d'Adobe modérateurs de ces forums est souvent d'attendre Hero ou de coder en AS3. Il y a donc une vraie demande de la part des développeurs qui, selon moi, ne sera pas satisfaite.
Les développements que j'ai effectué sur les composants pour mobiles font partie de mon travail chez Business Geografic. Ces composants ainsi que les librairies sur lesquelles ils reposent font partie d'un socle qui nous sert à créer des progiciels (propriétaire). En conséquent, je ne peux pas proposer de librairie en téléchargement, ni de snippet de code. Vous pouvez tout de même vous appuyer sur ce que j'explique dans les billets pour créer votre propre implémentation
.
Les ingrédients pour un bon framework
Avant de commencer, je vais donner les grands points sur lesquels j'essaie de m'appuyer dans tous mes développements qui sont, pour moi, les "best practices":
- Utiliser au maximum les bases du développement orienté objet
- Héritage
- Polymorphisme
- Objets les plus atomiques possibles (objets simple qui ne font qu'une petite chose et pas tout un process)
- Quand une architecture parait difficile à trouver, regarder du côté des Design Pattern, des gens y ont sûrement déjà réfléchi et trouvé une solution
- Factory
- Command
- Composition
- Ne pas essayer d'optimiser avant qu'il y ait des problèmes de performances
- Avoir le moins de couplage possible entre les classes lorsque celles-ci peuvent être réutilisée / héritées
- Utiliser une communication par évènement (+ ajout des Metadata) pour les processus avant de pouvoir être modulaire
- Pas d'utilisation de framework supplémentaire à Flex qui pourrait nuire à la simplicité du code
- Ne pas créer trop d'abstraction lorsque celle-ci n'est pas utile (pas de possibilité de ré-utilisation des composants par exemple). Préférer un code orienté métier.
Ce n'est peut-être pas grand chose mais une fois appliqués, ces principes m'ont permis de réaliser des développements performants, modulaire et facile à comprendre pour d'autres collaborateurs.
Les résultats attendus
Pour la création d'un bon framework mobile, on peut distinguer plusieurs objectifs:
- Ne pas "niveler par le bas", avoir une ergonomie cohérente avec les interfaces natives de chaque plate-forme. Ce point est sûrement le plus important car il permet à l'utilisateur d'avoir une prise en main directe.
- Permettre de s'interfacer un maximum avec les équipements disponibles sur le portable (GPS, accéléromètre, caméra, …)
- Ne pas simplement prévoir "Android ou Apple", le code doit pouvoir être évolutif suivant les devices mais aussi suivant le type de device (mobile / tablette)
- Respecter le style des interfaces natives
- Les parties spécifiques à chaque device doivent être présentes dans le framework mais invisibles pour les développeurs qui l'utilisent
- Prendre en compte les différences en termes de résolution (DPI / taille d'écran)
- Ne pas penser en terme d'interface Desktop, avoir un démarche orientée mobile / tactile
Les résultats obtenus
Après quelques semaines de développement (disons 2-3 à plein temps), les résultats sont déjà là. Je suis capable de créer facilement une application pour mobile avec AIR 2.5. Celle-ci est cohérente en terme de style et d'ergonomie avec les applications natives de chaque plate-forme. Pour l'instant, seules les devices Android et Apple sont prises en compte mais d'autres devices pourraient assez facilement être ajoutées. Je travaille par exemple sur le SDK BlackBerry fraîchement sorti en beta.
La détection de la device se fait automatiquement, suivant la propriété Capabilites.manufacturer. Cela me permet aussi de surcharger la récupération de cette variable pour pouvoir tester sur mon Android, une application avec le style Apple.
Le développement est complètement agnostique du type de portable utilisé. Ainsi, on ne crée pas une "pop-up Android", on crée une pop-up. Le code va déterminer tout seul si on est sur un Android ou un Apple (ou autre) et instancier la bonne pop-up.
Voici une petite vidéo présentant les résultats obtenus
:
Bon alors désolé pour la qualité de la vidéo qui n'est pas top, j'ai fait de mon mieux avec mes petits moyens (vidéo prise avec un appareil photo, parfois calé sur une petite montagne de bouquins
). Dans l'ordre, on peut voir:
- Une application Android créée avec AIR avec un look d'interface native Android (menu, boutons, listes, checkbox, …)
- Ensuite ce n'est pas un crash (on ne le voit pas sur la vidéo mais j'appuie sur le bouton HOME), je repasse sur l'écran d'accueil pour lancer une autre application. Celle-ci partage exactement le même code source sauf qu'elle est forcée "en mode Apple"
- La même application Android en mode Apple avec modification du style (boutons, liste, headers, …) et de l'ergonomie (ActionBar, menu permanent, …)
- La même application Android, lancée sur le simulateur BlackBerry, juste pour vous montrer que cela fonctionne sans aucune modification. On remarquera que je n'ai pas encore modifié le style pour BB, l'application est encore "en mode Apple"
Vous pouvez (parfois rapidement) le voir, tout est encore un peu en chantier. Pour l'instant, il me manque:
- La sauvegarde de l'état applicatif (qui se fera peut-être en ré-utilisant les classes de Flex 4.5)
- Des listes avec smooth-scrolling. Pour l'instant, j'utilise les listes Flex 3 car quand j'ai crée mes composants, Flex 4.5 n'était pas sorti. Flex 3 ne supporte pas le smooth-scrolling par défaut, il se cale toujours sur un élément de la liste lorsque l'on scroll, on ne peut pas avoir un demi-élément affiché ce qui fait un scrolling "haché". Je vais sûrement partir sur le composants Spark List qui gère cela par défaut
- Une version optimisée pour iPad mais je devrais en récupérer un pour le développement courant Novembre
- L'utilisation de plusieurs "set" d'icônes pour différentes devices et différentes résolutions / DPI
N'hésitez pas à réagir grâce aux commentaires !
Dans le prochain billet, une explication sur mes équivalents du View et du ViewNavigator.
Flex 4 – (2) Conception d'une architecture Flex orientée composant
Si vous suivez flex-tutorial, vous avez sûrement vu que je parlais que peu souvent des framworks MVC (Cairngorm, PureMVC, Mate, Parsley pour ne citer que les plus populaires). Cela vient du fait qu'après avoir regardé la plupart des frameworks, aucun ne me paraissait correct.
Les problèmes apportés par les frameworks MVC
Plusieurs raisons (subjectives) à cela:
- Aucun framework n'est "ultra-populaire" et écrase tous les autres. C'était le cas pour Cairngorm au départ car Adobe poussait à utiliser son produit mais le choix est maintenant plus hétérogène. Admettons que l'on apprenne le fonctionnement de Cairngorm et qu'on le maîtrise. Si vous tombez sur un poste où tous les projets utilisent PureMVC, vous pouvez mettre vos compétences au placard.
- La majorité des frameworks MVC pour Flex amènent avec eux, une architecture (dossiers/sources). Si vous décidez que pour une raison X, le framework ne convient plus à votre besoin, vous aurez un gros travail de refactoring à faire qui va se révéler laborieux (encore plus avec les bugs de Flex Builder 3, corrigés pour Flash Builder 4). Quand vous vous engagez sur un framework, vous êtes "couplé" à lui.
- Les frameworks basés sur les annotations (Mate, Parsley, …) ne vous imposent que très peu d'architecture et viennent se greffer sur votre code. Le problème est que de cette manière, beaucoup de choses se passent "under the hood" de manière un peu magique, et cela peut rendre le debugging laborieux.
- A la base, le paradigme MVC a été crée pour avoir des classes qui ne sont pas couplées entre elles et les plus atomiques possible (une des bases de la programmation OO). Pour certains frameworks MVC comme Cairngorm, vous devez sans cesse faire des héritages sur des classes du framework (tous les Event par exemple dérivent de CairngormEvent). D'autres comme Robotlegs vous obligent à enregistrer vos objets (à les "mapper") dans des Singletons. Cairngorm utilise lui aussi des Singletons pour un peu tout (Services, Model, …) ce qui va nuire à la ré-utilisabilité et à la modularité de votre code.
- Aucun des composants Flex disponibles sur le net n'est basé sur les classes d'un framework en particulier. Pour rester neutre, l'écrasante majorité des composants que l'on trouve sur le net ne sont pas écrits en se basant sur un framework. On peut donc se retrouver avec un code hétérogène.
- L'utilisation d'un framework implique que tous les développeurs comprennent les concepts d'utilisation du framework. Cela va venir s'ajouter au temps de développement du projet.
- En plus de "subir" la roadmap d'Adobe sur le SDK Flex, vous devrez parfois attendre la migration de telle ou telle fonctionnalité sur le framework choisi. Comme tous ne sont pas open source, vous pouvez vous retrouver bloqué.
Ces considérations sont générales à tous les framework. Chaque framework ayant ses spécificités, va aussi apporter d'autres points bloquants (trop long de tous les faire). Après il y a sûrement des points positifs à l'utilisation de chacun de ses frameworks mais qui, selon moi, ne pèse pas assez lourd dans la balance. Bien sûr, si vous voulez lancer un petit débat, vous pouvez laisser un commentaire à cet article
.
Adopter une approche différente
Pour le projet sur lequel je travaille actuellement, il me fallait donc trouver une solution cohérente, extensible et ré-utilisable pour l'architecture du projet. Ayant écarté l'utilisation d'un framework en particulier, il fallait donc trouver une solution qui ne m'oblige pas à re-inventer la roue. L'approche que j'ai adopté a été inspirée au départ de cet article:
Flex Best Practices – Models, Views, and Controllers
Le challenge avec l'utilisation du paradigme MVC (Model-View-Controller) est que chacun a un peu son implémentation (plus ou moins passive).
J'ai donc décidé de simplement intégrer les concepts-clé de la POO:
- Couplage faible entre les objets
- Pas de singletons (variables globales)
- Séparation of concerns (cloisonnement des fonctionnalités de chaque objet pour qu'il soit le plus atomique possible)
- Keep It Simple and Stupid & Don't Repeat Yourself
Flex RSL – Utilisation des RSL du Framework Adobe Flex
Les composants du framework Adobe Flex sont disponibles dans des librairies SWC. Elles peuvent être chargées à l'exécution comme RSLs (linkage dynamique). Les RSLs du framework sont supportées uniquement à partir de Flash Player 9.0.60. Les RSL du framework ne sont pas exactement comme les RSL de base, car ils sont signés. Ils ont aussi une extension différente: .swz, indiquant que le RSL est un "signed RSL". Seul Adobe peut créer des SWZ signés.
Vous les trouverez dans votre répertoire d'installation de Flex/Flash Builder:
C:\Program Files\Adobe\Flex Builder 3 Plug-in\sdks\3.2.0\frameworks\rsls
Pour définir le framework Flex comme RSL, rendez-vous dans les propriétés de votre projet Flex Build Path > Library Path. Depuis la ComboBox "Framework Linkage",choisissez "RSL". Le framework Flex sera ainsi séparé du SWF applicatif. Quand l'utilisateur va télécharger le framework une première fois, il va être conservé dans son cache. Encore mieux, ces librairies peuvent être utilisées depuis plusieurs domaines. Cela veut dire que les utilisateurs peuvent le récupérer depuis n'importe quel site déployé avec le Flex Framework en RSL, pas forcement celui de votre site.
Les RSL signés ne sont pas gardés en cache dans le cache du navigateur mais en local sur le disque. Ainsi, ils ne sont pas affectés par les utilisateurs qui vident leur cache.
Vous trouverez notamment les RSLs suivants:
- framework_3.2.0.3958.swz
- datavisualization_3.2.0.3958.swz
- rpc_3.2.0.3958.swz
Comme vous le constatez, le nom du fichier inclut la version du framework Adobe Flex ainsi que le numéro de build (3958).
Flex RSL – Utilisation de RSL standards
Les applications Adobe Flex modulaires, qui utilisent des librairies ré-utilisables sont les meilleurs candidates à l'utilisation des RSL. Dans cet article, on va voir comment utiliser ces RSLs dans la pratique.
Il y a quatre étapes à suivre quand on veut utiliser les RSL:
- Créer une librairie de composants / classes
- Compiler l'application Flex pour qu'elle utilise la librairie de composant
- Optimiser le RSL, si besoin est
- Déployer l'application et le RSL
Création d'une librairie de composants
La première étape consiste à créer une librairie ré-utilisable et d'en faire un package pour qu'elle puisse être facilement redistribuée. Flex Builder 3 permet de créer facilement ces projets librairie. A partir de ce projet, le compilateur Flex va compiler un fichier SWC. Un fichier SWC est une archive qui contient des composants Flex et d'autres éléments (images, font, …). Si vous décompressez cette archive, vous trouverez deux fichiers:
- Un fichier SWF, souvent appelé library.swf
- Un fichier XML "manifest" appelé catalog.xml, qui contient la liste des composants inclus dans la librairie.
Pour commencer la création d'une librairie Flex, créez un nouveau projet de type Flex Library Project et pas Flex Project:

Une librairie SWC peut être compilée de plusieurs manières, soit en ligne de commande avec le compilateur "compc", soit par Flex Builder. Dans notre cas, on va laisser Flex Builder faire le travail.
Flex Localization – Ajouter de nouvelles langues (locale)
Pour ajouter une langue nationale à votre projet, pour l'internationalisation, voici la marche à suivre:
- Ajoutez la langue à l'option locale de votre compilateur. Vous pouvez l'ajouter dans Flex Builder en faisant clic droit sur le projet puis Flex Compiler puis dans Additional Compiler Arguments. Voici par exemple, comment on ajoute la langue espagnole (en Espagne):
-locale=en_US,es_ES
Si vous n'utilisez pas Flex Builder mais plutôt mxmlc, éditer le fichier flex-config.xml et ajouter les langues avec la syntaxe suivante:
<locale>
<locale-element>en_US</locale-element>
<locale-element>es_ES</locale-element>
</locale>
- Assurez vous que vous avez bien crée le nouveau dossier ainsi que le nouveau fichier de propriété correspondant à la nouvelle langue. Ces fichiers doivent être liés au source path. Pour cela, jetez un oeil à cet article:
Flex Localization – Compilation de ressources dans une application Flex
- Il faut ensuite créer les Resource Bundles du framework pour la nouvelle locale
Création des Resource Bundles pour le framework Flex
L'option -locale définit quelle langue nationale inclure dans le source path. Elle indique aussi au compilateur quelle ressources utiliser pour le framework Flex (quelle langue pour le framework). Les composants du framework Flex comme les Label ou les Button utilisent des ressources, tout comme votre application peut le faire. Les ressources dont ont besoin ces classes sont situées dans des librairies comme framework.swc ou dans des Bundles séparés. Par défaut, les framework resources pour la locale en_US sont inclus avec le SDK Flex. Si vous ajoutez une locale à votre application, vous devez générer les ressources pour le framework dans cette langue.





