Ok

En poursuivant votre navigation sur ce site, vous acceptez l'utilisation de cookies. Ces derniers assurent le bon fonctionnement de nos services. En savoir plus.

20 septembre 2011

Mobile avec iUI

Dans l'article précédent, je présente le cadre d'évaluation de plusieurs frameworks pour le développement d'application mobile. Cet article présente le détail pour iUI.

Le framework iUI est plus restreint que jQuery Mobile en terme de composant et il est particulièrement bien adapté aux interfaces utilisant les listes hiérarchiques (drilldown) typiques des applications pour téléphone intelligent (iPhone en particulier). La base, la liste, est bien faite et fonctionne rapidement. Cependant, on atteint rapidement les limites, comme l'utilisation d'un unique toolbar (en haut) et l'absence de tabBar (en bas).

Comme il s'agit d'un petit framework, les performances sont excellentes.

La documentation est faible. Néanmoins, j'ai aimé utiliser ce framework, mais j'ai dû adapter la conception de l'interface en fonction de ce qu'il supportait.

Pour qui cible de petits appareils, notamment les iPhones, il est possible d'obtenir une grande productivité rapidement.

 

arbrIuiHome.png

arbrIuiListe.png

 

 

arbrIuiDetail.png


<!DOCTYPE html>
<%-- indique au fureteur de traiter la page en HTML5--%>
<html>
<head>
<title>Arbres HQ</title>
<METAHTTP-EQUIV="EXPIRES"CONTENT="Mon, 22 Jul 200211:12:01 GMT">
<metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
<metacharset="utf-8"/>
<linkrel="icon"type="image/ico"href="../images/logo.png">
<%-- les applications natives ne zoom pas, en general --%>
<%-- ces tags, propre a iOS permettent un look and feel plus natif--%>
<metaname="apple-touch-fullscreen"content="yes">
<metaname="apple-mobile-web-app-capable"content="yes">
<metaname="apple-mobile-web-app-status-bar-style"content="black">
<linkrel="apple-touch-startup-image"href="../images/splash.png"/>
<linkrel="apple-touch-icon"href="../images/logo.png">
<%-- iui specifics --%>
<metaname="viewport"
    content="width=device-width; initial-scale=1; maximum-scale=1; user-scalable=0;"/>
<linkrel="stylesheet"href="../iui.css"type="text/css"/>
<linkrel="stylesheet"href="../t/default/default-theme.css"
    type="text/css"/>
<script type="application/x-javascript" src="../iui.js"></script>
 
<script  type="text/javascript">
    function Filtrer(idOfSearchField){
        var arr =new Array();
        var countTreesShowingUp =0;
        arr = document.getElementsByClassName('list');
        for(var i =0; i < arr.length; i++){
            var obj = document.getElementsByClassName('list').item(i);
            if(obj.textContent
                    .indexOf(document.getElementById(idOfSearchField).value)==-1){
                obj.style.display ="none";
            }else{
                countTreesShowingUp++;
                obj.style.display ="block";
                document.getElementById('listCount').textContent = countTreesShowingUp +' arbre(s)';
            }
        }
    }// filtrer()
 
</script>
<style type="text/css">
body>.toolbar {
    top:0%;
    width:100%;
    position:fixed;
    z-index:99;
}
 
.inList {
    height:40px;
    margin-right:0.5em;
    float:left;
}
 
a.nomLatin {
    font-size:70%;
    /** mettre le code suivant si iPhone width = 360
    text-overflow: ellipsis ;
    overflow:hidden;
    white-space: nowrap;
    width:195px;
    margin-left:63px;
    **/
}
 
p.nomFr {
    font-size:60%;
    font-weight:normal;
    -webkit-margin-before:0em;
    color:#444;
    margin-left:72px;
}
 
.zone {
    position:relative;
    top:-10em;
    left:23px;
    width:2em;
    background:#42E01B;
    padding:0.2em;
    text-align:center;
    border:1pxsolid black;
    border-radius:5px;
}
 
.z5b {
    background:#cc7526;
}
 
.z5a {
    background:#fa9418;
}
 
.z4b {
    background:#adad2b;
}
 
.z4a {
    background:#e7d529;
}
 
.z3b {
    background:#9bc6cd;
}
 
.z3a {
    background:#84afb6;
}
 
.z2b {
    background:#b5dae2;
}
 
.z2a {
    background:#4ab4cc;
}
 
.z1b {
    background:#0095d7;
}
 
.z1a {
    background:#60c2ef;
}
 
.z0 {
    background:#c7e7f6;
}
 
.Coni,.Feui {
    position:relative;
    top:-10em;
    left:270px;
    width:2em;
    padding:0.2em;
    text-align:center;
    width:3em;
    height:3em;
}
 
.Coni span,.Feui span{
    display:none;
}
 
/** images de http://www.jenndickie.com/ctc/trees/index.html **/
.Coni {
    background-image:url(../images/conifere.png);
}
 
.Feui {
    background-image:url(../images/feuillu.png);
}
 
.fr,.lt,.en {
    margin-left:1em;
    margin-top:0px;
    margin-bottom:0.5em;
    position:relative;
    top:-55px;
}
 
.fr {
    font-weight:bold;
}
 
.lt {
    font-style:italic;
}
 
.en {
    font-size:80%;
    color:#444;
}
 
.distance {
position:relative;
top:-33px;
margin-left:1em;
font-weight:normal;
font-size:100;
-webkit-transform: scale(1) rotate(-24deg) translate(93px,4px) skew(47deg,0deg);
}
 
.distance:before{
    content:""
}
 
.carteLink {
    top:0.7em;
    position:relative;
    left:-1em;
}
 
.map {
    width:100%;
    }
</style>
 
</head>
 
<body>
<%-- T O O L B A R   there is only one toolbar in the app, this is a iUI limitation --%>
<divclass="toolbar">
    <h1id="pageTitle"></h1>
    <aid="backButton"class="button"href="#"></a>
    
</div>
 
<%-- M E N U   page d'accueil --%>
<ulid="home"title="Arbr"selected="true">
      <li><ahref="#list">Liste des arbres</a></li>
      <li><ahref="#favoris">Favoris</a></li>
      <li><ahref="#zone">Zone de rusticité</a></li>
      <li><ahref="#distance">Mesurer la distance minimale</a></li>
</ul>
 
<%-- L I S T E   de tous les arbres sur la page d'accueil --%>
<ulid="list"title="Liste">
    <li>
        
    <fieldset>
      <div>
         <labelfor="keyword">Filtrer :</label>
      <inputtype="text"name="q"id="keyword" placeholder="Nom"onkeyup="Filtrer(this.id);">
      </div>
   </fieldset></li>
    <liclass="group"id=listCount>Tous les arbres</li>
    <li><ahref="#search">Rechercher</a></li>
    <%-- on cré un li pour chacun des arbres --%>
    <g:each in="${arbreInstanceList}" status="i" var="arbreInstance">
        <liclass=list>
            <imgclass=inList src="${fieldValue(bean: arbreInstance, field: "vignetteURL")}"/>
            <aclass=nomLatin href="#${fieldValue(bean: arbreInstance, field: "id")}">${fieldValue(bean: arbreInstance, field: "nomLatin")}
                </a>
            <pclass=nomFr>${fieldValue(bean: arbreInstance, field: "nomFrancais")}</p>
        </li>
    </g:each>
</ul>
 
<%-- D E T A I L   de chacun des arbres, chacun sur sa page --%>
<g:each in="${arbreInstanceList}" status="i" var="arbreInstance">
<divid="${fieldValue(bean: arbreInstance, field: "id")}"
        title="${fieldValue(bean: arbreInstance, field: "nomLatin")}">
    <imgsrc="${fieldValue(bean: arbreInstance, field: "imageURL")}"/>
    <aclass="zone z${fieldValue(bean: arbreInstance, field: "zone")}"href="#zone">${fieldValue(bean: arbreInstance, field: "zone")}
        </a>
    <pclass="${fieldValue(bean: arbreInstance, field: "type")[0..3]}"><span>${fieldValue(bean: arbreInstance, field: "type")}
        </span></p>
    <pclass="fr">${fieldValue(bean: arbreInstance, field: "nomFrancais")}</p>
    <pclass="lt">${fieldValue(bean: arbreInstance, field: "nomLatin")}</p>
    <pclass="en">${fieldValue(bean: arbreInstance, field: "nomAnglais")}</p>
    <pclass="distance">${fieldValue(bean: arbreInstance, field: "distanceMinimale")}</p>
    <imgsrc="../images/distance.png"/>
    <aclass="favoris">Ajouter aux Favoris</a>
</div>
</g:each>
 
<%-- R E C H E R C H E R   écran de recherche --%>
<divid="search"title="Rechercher"class="panel">
   <fieldset>
      <divclass="row">
         <labelfor="select">Zone de rusticité</label>
         <ahref="#zone"class=carteLink>Carte</a>
         <selectid="select"name="selectname"size="1">
            <optionvalue="zone5b">5b</option>
            <optionvalue="zone5a">5a</option>
            <optionvalue="zone4b">4b</option>
            <optionvalue="zone4a">4a</option>
            <optionvalue="zone3b">3b</option>
            <optionvalue="zone3a">3a</option>
            <optionvalue="zone2b">2b</option>
            <optionvalue="zone2a">2a</option>
            <optionvalue="zone1b">1b</option>
            <optionvalue="zone1a">1a</option>
            <optionvalue="zone0">0</option>
         </select>
        
      </div>
      
      <divclass="row">
         <label>Conifères</label>
         <divclass="toggle"onclick="" toggled="true"><spanclass="thumb"></span><spanclass="toggleOn">1</span><spanclass="toggleOff">0</span></div>
      </div>
      <divclass="row">
         <label>Feuillus</label>
         <divclass="toggle"onclick="" toggled="true"><spanclass="thumb"></span><spanclass="toggleOn">1</span><spanclass="toggleOff">0</span></div>
      </div>
      <divclass="row">
         <labelfor="select">Distance minimale (mètres)</label>
         <selectid="select"name="selectname"size="1">
            <optionvalue="item15">15</option>
            <optionvalue="item14">14</option>
            <optionvalue="item13">13</option>
            <optionvalue="item12">12</option>
            <optionvalue="item11">11</option>
            <optionvalue="item10">10</option>
            <optionvalue="item9">9</option>
            <optionvalue="item8">8</option>
            <optionvalue="item7">7</option>
            <optionvalue="item6">6</option>
            <optionvalue="item5">5</option>
            <optionvalue="item4">4</option>
            <optionvalue="item3">3</option>
            <optionvalue="item3">2</option>
            <optionvalue="item0">0</option>
         </select>
      </div>
   </fieldset>
</div>
 
<divid="zone"title="Zone">
    <imgclass="map"src="http://www.hydroquebec.com/arbres/images/img_zones_rusticite.gif"/>
    <divclass="row">
        <p>Ma zone : 5b</p>
    </div>
</div>
 
<divid="distance"title="Mesurer distance minimale">
    <imgsrc="../images/distance.png"/>
</div>
 
</body>
</html>

14:33 Publié dans Mobile | Lien permanent | Commentaires (0)

Mobile avec Webapp-net

Dans l'article précédent, je présente le cadre d'évaluation de plusieurs frameworks pour le développement d'application mobile. Cet article présente le détail pour webapp-net.com.

Ce framework s'occupe principalement de l'interface et est axé sur les petits appareils, le look est celui de l’iPhone classique. Il supporte bien les listes simples et offre plusieurs composants d'interface intéressants, mais le manque de documentation et d'exemples le rende difficile à utiliser. La communauté autour de ce cadre logiciel semble inactive.

Au final, ce framework n'est pas très intéressant actuellement.

 

arbrWebappList.png

arbrWebappDetail.png

Voici le code avec webapp :

<!DOCTYPE html>
<!-- Webapp-net.com    est un framework sommaire peu documenté donc difficilement utilisable
    très simple a utilisée pour affichage de liste simple style iPhone -->
<html>
<head>
    <title>Demo Webapp.net</title>
    <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
    <metacharset="utf-8"/>
    <metaname="viewport"
        content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
    <metaname="apple-touch-fullscreen"content="yes">
    <metaname="apple-mobile-web-app-capable"content="yes">
    <metaname="apple-mobile-web-app-status-bar-style"content="black">
    <linkrel="apple-touch-startup-image"href="../images/splash.png"/>
    <linkrel="apple-touch-icon"href="../images/logo.png">
    <linkrel="icon"type="image/ico"href="../images/logo.png">
    <linkrel="stylesheet"href="${resource(dir:'Design',file:'Render.css')}"/>
    <script type="text/javascript"    src="${resource(dir:'Action',file:'Logic.js')}">
    </script>
<style>
.XXXinList {
    width:8em;}
.nomLatin {font-style:italic;}
</style>
</head>
 
<body>
<divid="WebApp">
    <divid="iHeader"><ahref="#"id="waBackButton">Retour</a><span
        id="waHeadTitle">Arbres HQ</span><ahref="#"id="waHomeButton">Home</a>
    <ahref="#"onclick="return WA.HideBar()"></a>
    <!-- Add an hidden form in the header. Will be shown pressing search button -->
    
    <formclass="iForm"id="headForm"action=""onsubmit="searchLoader()">
        <ahref="#"rel="action"id="gogo"class="iButton iBAction">Rechercher</a>
        <ahref="#"rel="back"class="iButton iBClassic">Annuler</a>
        <fieldset>
            <legend>Recherche</legend>
            <inputtype="search"name="search" placeholder="Chercher..."/>
        </fieldset>
    </form>
</div>
    
<divid="iGroup">
    <divclass="iLayer"id="waHome"title="Liste des arbres">
    <ahref="#"rel="action"onclick="return WA.Form('headForm')"id="oki"
        class="iButton iBClassic"><span>Rechercher</span></a>
    <divclass="iMenu">
        <ulclass="iArrow">
         <g:each in="${arbreInstanceList}" status="i" var="arbreInstance">
            <li><ahref="#_Arbre${fieldValue(bean: arbreInstance, field: "id")}"><imgclass=inList src="${fieldValue(bean: arbreInstance, field: "vignetteURL")}"/>
            <emclass="nomLatin">${fieldValue(bean: arbreInstance, field: "nomLatin")}</em>
            <small>${fieldValue(bean: arbreInstance, field: "nomFrancais")}</small></a></li>
        </g:each>    
        </ul>
    </div>
</div>
        
<g:each in="${arbreInstanceList}" status="i" var="arbreInstance">    
    <divclass="iLayer"id="waArbre${fieldValue(bean: arbreInstance, field: "id")}"title="Détail">
        <divclass="iBlock">
        <h1class="nomLatin">${fieldValue(bean: arbreInstance, field: "nomLatin")}</h1>
        <imgclass=inList src="${fieldValue(bean: arbreInstance, field: "imageURL")}"/>
        <p>${fieldValue(bean: arbreInstance, field: "type")}</p>
        <p>${fieldValue(bean: arbreInstance, field: "nomFrancais")}</p>
        <p>${fieldValue(bean: arbreInstance, field: "nomAnglais")}</p>
        <p>Zone : ${fieldValue(bean: arbreInstance, field: "zone")}</p>
        <p>Distance minimale : ${fieldValue(bean: arbreInstance, field: "distanceMinimale")}</p>
        </div>
    </div>
</g:each>
    
</div>
</div>
</body>
</html>

13:56 Publié dans Mobile | Lien permanent | Commentaires (0)

Mobile avec code maison

Dans l'article précédent, je présente le cadre d'évaluation de plusieurs frameworks pour le développement d'application mobile. Cet article présente le détail pour le code maison.

Si l'application est simple et la cible technologique restreinte, on peut s'en tirer avec du code maison simple. Premier avantage, on a le contrôle total et on peu garder la solution au plus simple. Deuxièmement, on réutilise nos compétences web de base. Principale faiblesse du modèle : la difficulté d'obtenir un look et un comportement "natif".

La mise en œuvre requiert un apprentissage des particularités du HTML5 et des CSS3 en plus des particularités de la plateforme cible, mais je crois que c'est une bonne façon de comprendre la valeur qu'apportent les frameworks.

En terme de performance, comme il y a peu de javascript et que le HTML est au minimum, elle est excellente.

C'est cette approche que nous avons utilisée dans notre première application en production, mais je ne pense pas que nous puissions prendre ce modèle si on espère être très productif à long terme.

Pour notre exemple de code maison, vous pouvez aussi consulter l'article que j'ai produit plus tôt et regarder le vidéo qui l'accompagne. Pour cet exemple, je ne me suis pas particulièrement forcé sur le look ni sur les fonctionnalités, car je voulais pouvoir faire une démonstration de moins d'une heure.

arbrCustom.png

Voici le code:

<!DOCTYPE html>
 
<html manifest="../arbre/manifest/">
<head>
    <title>Arbres HQ</title>
    <metahttp-equiv="Content-Type"content="text/html; charset=UTF-8">
    <metacharset="utf-8"/>
    <metaname="viewport"content="user-scalable=no, width=device-width, initial-scale=1.0, maximum-scale=1.0"/>
    <metaname="apple-touch-fullscreen"content="yes">
    <metaname="apple-mobile-web-app-capable"content="yes"><!--is this  buggy ??!!-->
    <metaname="apple-mobile-web-app-status-bar-style"content="black">
    <linkrel="apple-touch-startup-image"href="../images/splash.png"/>
    <linkrel="apple-touch-icon"href="../images/logo.png">
    <linkrel="icon"type="image/ico"href="../images/logo.png">    
<style type="text/css">
/*                                  G E N E R I Q U E   */
body{
    font-family: helvetica, trebuchet MS, arial, sans serif;
    margin:4px;
}
header {
    border-bottom:1pxsolid#999;
    margin-bottom:2px;
    background-color:silver;
}
 
#content {
    padding-top:10px;
}
 
#searchInput {
    font-size:1.3em;
}
 
.list {
    padding:2px;
    margin-bottom:12px;
        border:1pxsolid black;
    -webkit-border-radius:10px;
    -moz-border-radius:10px;
    border-radius:10px;
    background:#b4e391;/* Old browsers */
    background: -moz-linear-gradient(top,#b4e3910%,#61c41950%,#b4e391100%);/* FF3.6+ */
    background: -webkit-gradient(linear,lefttop,leftbottom, color-stop(0%,#b4e391), color-stop(50%,#61c419), color-stop(100%,#b4e391));/* Chrome,Safari4+ */
    background: -webkit-linear-gradient(top,#b4e3910%,#61c41950%,#b4e391100%);/* Chrome10+,Safari5.1+ */
    background: -o-linear-gradient(top,#b4e3910%,#61c41950%,#b4e391100%);/* Opera11.10+ */
    background: -ms-linear-gradient(top,#b4e3910%,#61c41950%,#b4e391100%);/* IE10+ */
    filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#b4e391', endColorstr='#b4e391',GradientType=0 );/* IE6-9 */
    background: linear-gradient(top,#b4e3910%,#61c41950%,#b4e391100%);/* W3C */
    }
    
#zone {padding:10px;}
p{margin:0;}
 
/* fin des styles communs  */
@mediaall and (orientation:landscape) {
    #content {
        -webkit-column-count:3;}
}/* landscape */
 
@media(orientation:portrait) {
    #content {
        -webkit-column-count:2;}
}/*portrait */
</style>
 
<script  type="text/javascript">
    function Filtrer(idOfSearchField){
        var arr =new Array();
        arr = document.getElementsByClassName('list');
        for(var i =0; i < arr.length; i++){
            var obj = document.getElementsByClassName('list').item(i);
            if(obj.textContent
                    .indexOf(document.getElementById(idOfSearchField).value)==-1){
                obj.style.display ="none";
            }else{
                obj.style.display ="block";
            }
        }
    }// filtrer()
</script>
 
<script  type="text/javascript">
    function UpdateZone(){
        if(window.navigator.geolocation){
        window.navigator.geolocation.getCurrentPosition(successCallback);
 
        function successCallback(position){
            alert("Position : "+position.coords.longitude +", "+ position.coords.latitude );
            }
        }
    }// UpdateZone()
</script>
</head>
 
<body>
<header>
     <inputid=searchInput type="search" placeholder="Rechercher..."onkeyup="Filtrer(this.id);"  />
        <spanid=zone onClick="UpdateZone();">Ma Zone</span>
</header>
<sectionid=content>
    <g:each in="${arbreInstanceList}" status="i" var="arbreInstance">
        <divid=${fieldValue(bean: arbreInstance, field: "id")} class="list"tabindex="1">
            <imgsrc="${fieldValue(bean: arbreInstance, field: "vignetteURL")}"/>
            <pclass="fr">${fieldValue(bean: arbreInstance, field: "nomFrancais")}</p>
            <pclass="lt">${fieldValue(bean: arbreInstance, field: "nomLatin")}</p>
            <pclass="en">${fieldValue(bean: arbreInstance, field: "nomAnglais")}</p>
            <pclass="zone">${fieldValue(bean: arbreInstance, field: "zone")}</p>
            <pclass="distance">${fieldValue(bean: arbreInstance, field: "distanceMinimale")}</p>
        </div>
    </g:each>
</section>
</body>
</html>

13:48 Publié dans Mobile | Lien permanent | Commentaires (0)

Tous les frameworks mobiles ne sont pas identiques

Depuis quelques mois, je recherche un framework pour faciliter le développement d'applications mobiles pour les besoins de l'entreprise. Je rends compte ici de mes premiers constats.

D'abord, il faut dire que nous cherchons un framework qui a les caractéristiques suivantes :

  • Permets une mise en œuvre rapide, car il s'agit d'une première évaluation,
  • Est relativement bien documenté, car je n'ai pas de temps à perdre
  • Présente un aspect professionnel et de qualité, car on veut faire bonne impression
  • Permets l'affichage de listes, de détails et saisie de formulaire
  • Est bien adapté au iPad, car c'est notre cible court terme à l'interne
  • Ne requiert pas le Apple SDK ou xCode, car nos postes de développeurs sont barrés et nous ne pouvons installer aucun package (.msi)
  • Ne requiert pas Objective-C, car limité à iOS et on ne possède pas cette expertise
  • Permets de développer sous Windows XP
  • Supporte iOS, et idéalement, Android
  • Idéalement facilite la gestion des données, synch, ajax, localstorage…, car on parle toujours à un backend

On a fait le tour rapidement de plusieurs frameworks, qui n'ont pas été retenus (et la principale raison de l'exclusion)  :

  • Appcelarator Titanium, car requiert installation, Apple SDK et xCode
  • PhoneGap, car requiert installation, Apple SDK et xCode
  • SproutCore, car requiert installation d'un msi
  • ModelBaker, car requiert Mac OS X
  • RhoMobile,  car requiert installation, Apple SDK et xCode
  • JoApp, car pas d'exemples de liste et qualité moyenne
  • M-Project, car requiert installation de cygwin et autres
  • Dojo mobile, car semble lent à charger
  • Zepto, car difficile de savoir ce que ça fait et par où commencer
  • Mobl, car peu d'exemples et documentation
  • Skeleton, car manque de temps
  • jQuery Touch, car manque de temps

Notez, que certains de ces outils présentent quand même un véritable potentiel et que je n'exclus pas de les évaluer éventuellement. De fait, en fonction de vos besoins, ils peuvent être plus intéressants que ceux que nous avons évalués. Considérez aussi que tous les frameworks mobiles évoluent rapidement et que cette évaluation représente la situation au d/but de septembre 2011.

Voici ceux que nous avons expérimentés :

L'expérimentation

Aux fins de l'expérimentation, j'utilise un extrait de la base de données sur les arbres et arbustes ornementaux du Québec, publié sur le site d'Hydro-Québec.

 arbresHQ.png

L'application backend est développée avec Grails. En fonction des résultats obtenus durant le développement des prototypes, chacun des frameworks a été poussé plus ou moins loin. D'ailleurs, les exemples de code que je publie ne sont pas tous fonctionnels au même niveau.

Comme cet article est trop long pour tenir dans une page, vous trouverez le détail de chacune des expérimentations dans un article séparé, disponible par le lien dans le tableau suivant :

 Framework 

Commentaires

Code maison

Simple, mais colle moins au look de la plateforme

Webapp-net

Simple, peu de documentation et de composants

iUI

Simple, rapide, axé liste drill-down

jQuery mobile

Simple, riche, lent, large support appareil

Sencha

Riche, professionnel, complexe, touch

Globalement, ce dont on s'aperçoit, c'est que chacun des frameworks tente de résoudre des problématiques différentes. Cela est aussi vrai pour ceux que nous n'avons pas évalués.

Si je cible des Smartphones, en particulier les iPhones et iPod Touch, iUI va me donner une interface rapide, facile à développer, mais rudimentaire. À l'autre extrême, Sencha me permet de créer des applications qui tirent réellement profit de l'interface tactile et supportent très bien les Smartphones et les tablettes avec un large éventail de composants raffinés, mais va demander plus d'efforts. Entre les deux, jQuery mobile me permet d'atteindre un très large spectre d'appareil mobile avec un ensemble de composants de base.

Au moment d'écrire ces lignes, on annonce la sortie prochaine de Sencha touch 2.0 et je découvre d'autres frameworks comme bolt.js et javelin.js. On ne verra donc pas à court terme une évaluation finale. La leçon est de choisir celui qui semble le mieux correspondre aux besoins et aux contraintes, de prototyper les éléments clé de l'application et de foncer, en sachant que vous aurez à maîtriser plus d'un framework dans les prochaines années.

13:33 Publié dans Grails, Mobile | Lien permanent | Commentaires (1)