Récits d'un GeekTrotter Carnet de bord binaire

22janv./1125

Développez rapidement des applications pour les mobiles (iPhone, Android, WP7, BB, Symbian) avec Rhomobile Rhodes

Hier encore, je n'avais aucune idée de comment écrire des programmes pour les smartphones comme l'iPhone, Android, Windows Phone ou BlackBerry.
Aujourd'hui, ma première application tourne déjà sur mon téléphone Android...

Pour un premier test de création d'application mobile, j'ai essayé de faire une application qui récupère les dernières news depuis le flux Atom de mon école (Keio SDM) et les affiche de façon "native" sur les téléphones.
Hier je n'avais aucune connaissance sur la programmation pour téléphones si ce n'est que "l'iPhone utilise l'horrible Objective-C et Java utilise le lourd Java".
Aujourd'hui, mon application ressemble à ça...

...est écrite en pur Ruby et est 100% native sur iPhone, Android, Windows Mobile et BlackBerry !
Comment est-ce possible ?! Grâce à un framework de développement mobile puissant, léger, facile à utiliser et intuitif, j'ai nommé : Rhodes (par Rhomobile).
Voyons dans cet article comment en arriver là.

Introduction

Quand vous êtes confronté à un nouveau problème, la première chose qu'on fait souvent est... de chercher sur Google !
Et c'est ce que j'ai fait, pour vite me rendre compte que si je voulais écrire des applications natives pour téléphones, j'allais devoir programmer dans différents langages de programmation pour différents OS (voire même me mettre à de nouveaux langages comme par exemple l'immonde Objective-C pour l'iPhone), à moins de n'utiliser des "frameworks" pour le développement sur mobile qui font tout le sale travail de conversion pour moi à partir d'une source commune.

Appcelerator Titanium

Et parmi ces framework, le plus populaire semble être Appcelerator Titanium.
D'après leur site web, ça permet d'utiliser les "technologies web" (JavaScript, Python, Ruby) pour développer des applications natives pour Android et iPhone.
Ca à l'air prometteur, pas vrai !

Donc j'ai installé ladite plateforme, téléchargé un exemple sur leur site et tenté de le faire tourner.
Ce fût la dernière chose que je fis avec ce framework... Le logiciel n'a jamais réussi à se connecter au SDK d'Android (pourtant bien installé, avec son path bien définit et "adb" dans le bon dossier...). Le logiciel restait bloqué sur "loading...".
Bien, essayons alors leurs morceaux de codes de test dans la "Sandbox" (bac à sable).
C'est un des onglets du logiciel qui permet en théorie de tester des bouts de code "dans le nuage".
J'ai sélectionné l'exemple "hello world" en Python et cliqué sur "Launch".
Rien ne se passe... Je peux attendre longtemps, rien ne bouge !

Bon étant donné la popularité du logiciel, le problème vient sans doute de moi...
Cela dit, bien que l'interface soit cool, ça m'a pas vraiment persuadé d'investiguer plus que ça...

Rhomobile Rhodes

J'ai donc donné sa chance à un autre framework, apparemment moins populaire.
Son petit nom est "Rhodes", bébé de la Rhomobile family.
Là où Appcelerator Titanium se contente de proposer l'iPhone et Android, Rhodes propose en plus Windows Mobile, RIM (BlackBerry) et Symbian !
On est dans du vrai "cross-platform" là, ça rigole pas !
Par contre, vous n'avez pas autant de choix quant au langage de programmation : il va falloir coder en Ruby.
Un programme écrit en Ruby pourra ensuite être déployer en une application native sur chacun des OS supporté.

Mais est-ce une tare d'utiliser Ruby ? Après l'avoir utilisé deux jours... clairement pas !
Rhodes est grandement inspiré de Rails et hérite des bonnes idées de ce framework : Database Abstraction (bien que moins puissante que Papa Rails), MVC (Model-View-Controller), génération automatique de code (similaire à l’échafaudage (scaffolding) de Rails, aussi via rake) et plein de choses que j'ai pas encore découvertes !

Voyons comment j'en suis arrivé en 2 jours à une application complète qui tourne sur mon téléphone en partant de 0.
Primo, on a besoin d'un kit de développement (SDK) d'un OS cible (un seul suffit pour les tests).
Le plus simple à installer et disponible sur toutes les plateformes (contrairement à un OS très fermé disponible uniquement sur des ordinateurs à pomme dont je ne citerais pas le nom... ><) est sans conteste Android SDK.

A vous de choisir celui que vous voulez, mais en guise d'information j'explique comment installer le SDK d'Android.

Installer Java SDK

Pour utiliser l'Android SDK, vous allez avoir besoin de Java SDK (étant donné que les applications Android sont nativement en Java).
Donc si vous n'avez pas encore le Java SDK, il est temps de l'installer.
Allez sur la page de téléchargement du site Java et téléchargez le dernier SDK pour votre système.

Note : Sous Windows, installez la version 32 bits de Java SDK, même si vous avez un OS 64 bits. Android SDK ne fonctionne qu'avec la version 32 bits (pour le moment ?).
Sous Linux, utilisez de préférence le SDK propriétaire de Sun (vous pouvez choisir via "alternatives") bien que ça peut aussi marcher avec OpenSDK (mais je n'ai pas vérifié)

Installer Android SDK

Aller sur le site Android Developers et installez le SDK.
Lancez le SDK Manager (proposé à la fin de l'install sous Windows ou dispo sous /tools/android sous Linux) et installez les paquets que vous voulez (probablement le SDK pour Android 2.3 et les différentes mises à jour).
Depuis cette même page, téléchargez le Android NDK qui aide à créer des applications natives dont la performance est critique. Il suffit d'extraire l'archive quelque part (probablement à côté du SDK).

Note : N'installez pas le SDK dans un dossier qui contient des espaces (donc pas dans le "Program Files" par exemple !), il ne sera pas utilisable (préférez par exemple 'C:\android-sdk-windows' et 'C:\android-ndk-r5' instead).

Installer Ruby et Rhodes

Passons à l'installation de Ruby et de Rhodes.

Sous Linux, il suffit d'installer les paquets "ruby", "rubygems", et les gems rake et rhodes ("sudo gem install rake rhodes").
Sous Windows, si vous avez déjà Ruby et RubyGems, il suffit de lancer un invité de commande avec Ruby ("Start command prompt with Ruby" from the windows menu) et de faire "gem install rake rhodes".
Si vous n'avez pas Ruby, vous pouvez installer Ruby et Rhodes avec un pack d'installation tout-en-un magique : Instant Rhodes.

C'est tout ce dont vous avez besoin pour bénéficier du framework Rhodes.
Configurons-le. Lancez un invité de commande Ruby et entrez "rhodes-setup".
Suivez les instructions pour configurer Rhodes.

Par exemple pour moi :

ruby 1.9.2p136 (2010-12-25) [i386-mingw32]

C:\Users\Thomas>rhodes-setup
We will ask you a few questions below about your dev environment.

JDK path (required) (C:/Program Files/Java/jdk1.6.0_23):
Android SDK path (blank to skip) (): C:\android-sdk-windows
Android NDK path (blank to skip) (C://android-ndk-r5):
Windows Mobile 6 SDK CabWiz (blank to skip) ():
BlackBerry JDE 4.6 (blank to skip) ():
BlackBerry JDE 4.6 MDS (blank to skip) ():
BlackBerry JDE 4.2 (blank to skip) ():
BlackBerry JDE 4.2 MDS (blank to skip) ():

If you want to build with other BlackBerry SDK versions edit: C:/Ruby192/lib/ruby/gems/1.9.1/gems/rhodes-2.2.6/rhobuild.yml

C:\Users\Thomas>

Et voilà, Rhodes est configuré !

Note : Si vous avez des problèmes avec rake et son 'bin_path', supprimez les fichiers rake.gemspec et rake-0.8.7.gemspec du dossier \lib\ruby\gems\1.9.x\specifications et relancez "gem install rake"

Hello World

Pour créer une nouvelle application, la seule chose à faire est d'étendre le framework.
Générons une sorte d'"hello world" en une ligne.
Depuis l'invité de commandes, entrez "rhodes app myapp" (en changeant "myapp" par ce-que-vous-voulez)

Ça créera la structure d'une application :

[thomas@myhost rhodes]$ rhodes app myapp
Generating with app generator:
     [ADDED]  myapp/rhoconfig.txt
     [ADDED]  myapp/build.yml
     [ADDED]  myapp/app/application.rb
     [ADDED]  myapp/app/index.erb
     [ADDED]  myapp/app/index.bb.erb
     [ADDED]  myapp/app/layout.erb
     [ADDED]  myapp/app/loading.html
     [ADDED]  myapp/Rakefile
     [ADDED]  myapp/app/loading.png
     [ADDED]  myapp/app/helpers
     [ADDED]  myapp/icon
     [ADDED]  myapp/app/Settings
     [ADDED]  myapp/public

Entrez dans le dossier (cd myapp) et vous pouvez dès à présent exécuter "rake run:android" pour démarrer l'application dans un émulateur Android.
La première fois que vous lancez "rake run:android" vous pourrez choisir de paramétrer manuellement la machine virtuelle Android.
Pressez simplement ENTRER pour laisser Rhodes s'occuper de ça et ce sera configuré.

Une fois cela fait, votre première application va démarrer dans un émulateur Android ressemblant à ça :

2011-01-21-214416_1280x705_scrot

Note : L'émulateur Android est très lent ! Ca peut prendre jusqu'à trois minutes pour démarrer et lancer l'application.

Créez votre propre application

Hello World c'est cool, mais on veut quelque chose de plus réel.

Comme annoncé dans l'introduction, nous allons écrire un programme qui récupère un flux Atom qui affiche de façon plus naturelle les news dans un téléphone mobile.
Nous voulons une liste avec les titres des news et que lorsqu'on clique (ou plutôt "tapote") sur un titre, ça nous affiche le contenu de la news.
Le flux Atom que je prends dans l'exemple est le suivant : http://www.sdm.keio.ac.jp/en/atom.xml
(flux Atom en Anglais des dernières news de mon école : Keio University, Graduate School of SDM).

Modèle

Primo, créons le modèle de notre application.

Nous allons stocker les news dans un modèle "Feed" et chaque "feed" aura un titre, une date, un lien, un contenu et une langue.
Nous générons ce modèle automatiquement dans Rhodes :

[thomas@myhost myapp]$ rhodes model Feed title,date,link,content,lang
Generating with model generator:
     [ADDED]  app/Feed/index.erb
     [ADDED]  app/Feed/edit.erb
     [ADDED]  app/Feed/new.erb
     [ADDED]  app/Feed/show.erb
     [ADDED]  app/Feed/index.bb.erb
     [ADDED]  app/Feed/edit.bb.erb
     [ADDED]  app/Feed/new.bb.erb
     [ADDED]  app/Feed/show.bb.erb
     [ADDED]  app/Feed/feed_controller.rb
     [ADDED]  app/Feed/feed.rb
     [ADDED]  app/test/feed_spec.rb

Comme on peut le voir, cela a généré pas mal de fichiers pour nous.

Nous avons de quoi créer, éditer et supprimer des feeds directement depuis l'application.
Vous pouvez jeter un coup d'oeil à ces fichiers pour comprendre comment marche Rhodes.
Dans notre cas, nous n'avons pas besoin d'ajouter, supprimer ou modifier des feeds directement depuis l'application.
Nous voulons récupérer automatiquement ces feeds depuis le flux Atom.
Donc vous pouvez supprimer les templates "edit" et "new" (.erb) et supprimer les méthodes edit/update/create/delete du controlleur (feed_controller.rb).

XML

Ce que nous voulons, c'est de remplir la base de donnée avec les feeds récupérés dans le flux Atom (XML).
Donc nous avons besoin d'un lecteur XML en Ruby, et, bien sûr, ce n'est pas ce qui manque !
Rhodes gère le populaire ReXML et possède en plus sa propre implémentation basée sur ReXML : RhoXML (plus légère que ReXML donc plus rapide, mais avec moins de fonctions). Malheureusement, RhoXML ne gère pas les tags CDATA et le flux Atom de test que j'ai choisi en contient...
Nous utiliserons donc ReXML qui marche très bien.

Pour ajouter la prise en charge de ReXML, il suffit d'ajouter “rexml” et “set” à la liste des extensions dans le fichier the build.yml (à la racine de votre application) :

extensions: ["json", "rexml", "set"]

Menu de départ

Quand nous lançons l'application, nous voulons afficher une liste des feeds.
Donc nous voulons appeler la méthode "index" (par défaut) de "Feed".

Pour cela, il suffit d'éditer notre rhoconfig.txt file (à la racine de votre app) comme suit :

# Startup page for your application
start_path = '/app/Feed'

def index

Et ce que nous voulons faire lorsqu'on lance l'application c'est lister les feeds, donc faisons ça simplement en modifiant la méthode index de feed_controller.rb comme suit :

  def index
    @feeds = Feed.find(:all)
    if @feeds.empty? then
      self.update
    else
      render :action => :index, :back => :exit
    end
  end

Si on a déjà les feeds dans la base de donnée, nous affichons juste la liste de ceux-ci.
Sinon, nous les mettons à jour.

def update

La spécification complète de la méthode update est disponible dans l'archive du code source de cette application à la fin de l'article.
Je ne copie ici que la partie la plus importante, celle qui charge le contenu XML et en extrait chaque élément dans notre variable @feeds.

require 'rexml/document'
#@@get_result contains the XML text (as a string)
doc = REXML::Document.new(@@get_result)
REXML::XPath.each(doc,"//feed/entry/") do |e|
  Feed.create(:title => e.elements['title'].text,
              :link => e.elements['link'].attributes['href'],
              :date => e.elements['published'],
              :content => e.elements['content'].texts().at(1),
              :lang => e.elements['content'].attributes['xml:lang'])
end

def refresh

Nous voulons aussi pouvoir "rafraîchir" la liste des feeds car lorsque nous relançons l'application, si vous avez remarqué au début de notre méthode index, si nous avons déjà des feeds dans la base de donnée, nous affichons ceux-la sans revérifier le fichier en ligne.
Et comme la base de données n'est pas détruite lorsqu'on quitte l'application, les news seront simplement ré-affiché lors de la prochaine exécution sans remettre à jour depuis internet.
Evidemment, à chacun d'implémenter ça comme il veut ! J'ai préféré procéder ainsi, et du coup il me faut une méthode "refresh" pour forcer la lecture du flux Atom.

def refresh
  Feed.delete_all
  redirect :action => :update
end

def show

Ensuite lorsqu'on utilisateur tapote le titre d'un feed, nous voulons afficher le contenu de ce feed.
Pour cela, la méthode "show" a déjà été implémentée et nous n'avons même pas à la changer !

def show
  @feed= Feed.find(@params['id'])
  if @feed
    render :action => :show
  else
    redirect :action => :index
  end
end

Les vues (index, show)

Enfin, il nous faut changer les "vues" pour afficher les informations qu'on veut.
Voyons les plus importantes d'entre elles : index.erb et show.erb

L'index propose un bouton en haut de l'écran pour rafraîchir manuellement les entrées et liste ensuite toutes les news.

<h1>SDM News</h1>

Le résultat :

Android_SDM_News_01

Le show.erb affiche le titre d'une news, sa date et son contenu.

<h1><%= @feed.title %></h1>
  • <%= @feed.title %>
  • <%= @feed.date %>
  • <%= @feed.content %>

Le résultat :

Android_SDM_News_04

Et... c'est terminé !
J'ai ajouté quelques vérifications, le support du multi-lingue (news en anglais et en japonais) et l'application était terminée !

Conclusion

En plus de permettre de créer rapidement des applications mobiles, Rhodes supporte les API natives des smartphones.
C'est un framework réellement cross-platform étant donné qu'on peut déployer nos applications sur les 5 fabricants d'OS pour téléphones (iPhone, Android, Windows Phone, BlackBerry et Symbian).
Ruby est un langage de programmation très agréable et facile à utiliser.
L'architecture MVC et le Database Abstraction hérité de Rails font qu'il est facile de maintenir le code.

Les IDEs qui marchent avec Ruby/Rails marche aussi très bien avec Rhodes.

RubyMine_Screenshot

Vous pouvez voir quelques captures d'écrans de ladite application ici :

Vous pouvez télécharger le code source de l'application créée dans ce tutorial ici : sdmnews.zip.
Depuis votre téléphone Android, vous pouvez installer l'application en téléchargeant et installant l'application suivante : sdmnews.apk
Vous devez autoriser les sources non identifiées pour installer cette application (Settings > Applications > Unknown sources) étant donné que je n'ai pas publié l'application sur le Market (pas encore ?).

Si vous avez des commentaires ou des questions, faites-vous donc plaisir !

  • Pingback: serverpronto coupon()

  • Pingback: Honey Curson()

  • Pingback: Cody Shappell()

  • Pingback: Cary Sleaford()

  • Pingback: jump manual book()

  • Eqbal

    Thanks a lot for sharing this, very helpful.

    Anyway, I have few questions for you if you don’t mind.

    – Do you know any solid smartphone App that used Rhomobile? this could give it more credibility. since I as you said with your post, it is not a very well knows framework. I don’t wanna invest much time developing the solution then to get refused from apple for that reason.

    – Did you notice any performance issues? specially with the UI? as it is not a purely native application (unlike RubyMotion or Objective-C)

    – Do you have any idea of the pricing? for commercial uses is there any fees or is it totally free app ?

    Thanks in advance for your time

    • ThomasDalla

      Hi Eqbal,

      Please note this post was written more than 2 years ago and the mobile ecosystem changes quickly.
      Rhomobile has been bought by Motorola Solutions by then and I haven’t heard much since:
      http://www.motorolasolutions.com/US-EN/Business+Product+and+Services/Software+and+Applications/RhoMobile+Suite

      As of today, I would recommend other solutions like Appcelerator Titanium (especially Alloy framework) or Sencha Touch.
      Titanium creates native application so the look and feel as well as responsiveness is great.
      Sencha Touch is an hybrid application so looks less « native » and might be slightly slower but development is highly simplified and result is the same in all platforms.

  • SuperByteMan

    Hi, I notice that you say that this page is three years old and that things have changed. I’m 63, know various versions of BASIC as my first major language (and still favorite, though mostly under old DOS basics like QBX 7.2 {Quick Basic Extended Professional Edition}), but would like to teach myself to program for smartphones and other devices (watches, pads, etc.). What do you now recommend as the best for someone with very little experience in programming in versions later than DOS. Thanks for any advice you can offer.

    • ThomasDalla

      Hi,
      There is no age limit to enjoy programming 🙂
      Indeed, this article is very old. I won’t recommend Rhodes now.
      Instead, I would suggest you to try some HTML5 frameworks, such as Ionic (very promising) or Sensa Touch.
      For a more native result, I’d try Xamarin or go completely native (at least for Android, for iOS it’s a bit of a waste learning a language just for one platform).