Vous êtes sur la page 1sur 239

Lee S.

Barney
Dveloppez des applications pour
iPhone
avec HTML,
CSS et
JavaScript
e S. Barney
Traduit par Herv Soulard,
avec la contribution de Julien Desrosiers


L E P R O G R A M M E U R
Dveloppez
des applications
pour liPhone

avec HTML, CSS et JavaScript
Lee S. Barney
iPhone Livre Page I Vendredi, 30. octobre 2009 12:04 12
Pearson Education France a apport le plus grand soin la ralisation de ce livre an de vous four-
nir une information complte et able. Cependant, Pearson Education France nassume de respon-
sabilits, ni pour son utilisation, ni pour les contrefaons de brevets ou atteintes aux droits de tierces
personnes qui pourraient rsulter de cette utilisation.
Les exemples ou les programmes prsents dans cet ouvrage sont fournis pour illustrer les descriptions
thoriques. Ils ne sont en aucun cas destins une utilisation commerciale ou professionnelle.
Pearson Education France ne pourra en aucun cas tre tenu pour responsable des prjudices
ou dommages de quelque nature que ce soit pouvant rsulter de lutilisation de ces exemples ou
programmes.
Tous les noms de produits ou marques cits dans ce livre sont des marques dposes par leurs
propritaires respectifs.
Aucune reprsentation ou reproduction, mme partielle, autre que celles prvues larticle L. 122-5 2 et 3 a) du code de la
proprit intellectuelle ne peut tre faite sans lautorisation expresse de Pearson Education France ou, le cas chant, sans le
respect des modalits prvues larticle L. 122-10 dudit code.
No part of this book shall be reproduced, stored in a retrieval system, or transmitted by any means, electronic, mechanical,
photocopying, recording, or otherwise, without written permission from the publisher.
Publi par Pearson Education France
47 bis, rue des Vinaigriers
75010 PARIS
Tl. : 01 72 74 90 00
www.pearson.fr
Mise en pages : TyPAO
ISBN : 978-2-7440-4096-2
Copyright 2009 Pearson Education France
Tous droits rservs
Titre original : Developing Hybrid Applications for the iPhone :
using HTML, CSS, and JavaScript to Build Dynamic Apps
for the iPhone
Traduit par Herv Soulard,
avec la contribution de Julien Desrosiers
ISBN original : 978-0-321-60416-3
Copyright 2009 Pearson Education, Inc.
All rights reserved
dition originale publie par Addison-Wesley
iPhone Livre Page II Vendredi, 30. octobre 2009 12:04 12
Sommaire
Prface .................................................... 1
1. Dvelopper avec Dashcode et Xcode 7
2. Modularit JavaScript ...................... 33
3. Interfaces utilisateur ......................... 57
4. GPS, acclromtre
et autres fonctions natives
avec QuickConnectiPhone ............... 91
5. GPS, acclromtre
et autres fonctions natives
avec PhoneGap .................................. 115
6. Cartes Google ..................................... 133
7. Bases de donnes ................................ 151
8. Donnes distantes .............................. 185
A. Introduction JSON ........................ 205
B. Plan de dveloppement
pour QuickConnectFamily .............. 213
C. Plan de dveloppement
pour PhoneGap ................................. 219
Index ....................................................... 223
iPhone Livre Page III Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page IV Vendredi, 30. octobre 2009 12:04 12
Table des matires
Prface ............................................................... 1
Outils pour le dveloppement
dapplications hybrides .................................. 1
Comment utiliser ce livre ............................... 3
Ressources en ligne ....................................... 5
Prrequis ........................................................ 5
Remerciements .............................................. 6
propos de lauteur ...................................... 6
Contacter lauteur .......................................... 6
1. Dvelopper avec Dashcode et Xcode ........... 7
Section 1 : utiliser Dashcode
et le modle QuickConnect ............................ 8
Section 2 : utiliser Xcode
et le modle QuickConnect ............................ 12
Section 3 : les bases dObjective-C ............... 16
Section 4 : structure Objective-C dune
application QuickConnectiPhone .................. 19
Section 5 : structure Objective-C
dune application PhoneGap .......................... 23
Section 6 : embarquer du contenu web
avec QuickConnectiPhone ............................. 25
Section 7 : embarquer du contenu web
avec PhoneGap ............................................... 29
En rsum ...................................................... 30
2. Modularit JavaScript ................................ 33
Section 1 : modularit ................................... 33
Section 2 : modularit avec le framework
JavaScript QuickConnect ............................. 35
Section 3 : conception modulaire
dans QuickConnectiPhone ............................ 44
Section 4 : implmentation
des contrleurs mtier
et dafchage ................................................. 49
Section 5 : implmentation
dun contrleur derreur ................................ 53
Section 6 : tapes de cration
dune fonctionnalit de lapplication ............. 54
En rsum ...................................................... 55
3. Interfaces utilisateur ................................... 57
Section 1 : guide de linterface
utilisateur dApple ......................................... 57
Section 2 : interfaces fondes sur les
listes et sur Navigateur .................................. 61
Section 3 : applications non fondes
sur des listes .................................................. 64
Section 4 : applications dimmersion ............ 69
Section 5 : crer et utiliser des
transformations CSS personnalises ............. 71
iPhone Livre Page V Vendredi, 30. octobre 2009 12:04 12
VI Dveloppez des applications pour liPhone
Section 6 : crer et utiliser un module
de glisser-dposer, de redimensionnement
et de rotation ................................................. 78
En rsum ..................................................... 89
4. GPS, acclromtre et autres fonctions
natives avec QuickConnectiPhone ............. 91
Section 1 : activation de lappareil
en JavaScript ................................................. 92
Section 2 : activation de lappareil
en Objective-C .............................................. 98
Section 3 : implmentation Objective-C de
larchitecture de QuickConnectiPhone ......... 107
En rsum ..................................................... 113
5. GPS, acclromtre et autres fonctions
natives avec PhoneGap ............................... 115
Section 1 : activation de lappareil
en JavaScript ................................................. 115
Section 2 : activation de lappareil
en Objective-C .............................................. 122
En rsum ..................................................... 130
6. Cartes Google ............................................... 133
Section 1 : afcher une carte dans une
application JavaScript QuickConnect ........... 133
Section 2 : implmentation Objective-C
du module de cartographie
de QuickConnect ........................................... 138
En rsum ..................................................... 149
7. Bases de donnes ......................................... 151
Section 1 : application BrowserDBAccess ... 151
Section 2 : utilisation des bases de donnes
SQLite avec WebView ................................... 153
Section 3 : utilisation de bases de donnes
SQLite natives ............................................... 158
Section 4 : utilisation de DataAccessObject
avec les bases de donnes du moteur
WebKit ........................................................... 161
Section 5 : utilisation de DataAccessObject
avec les bases de donnes natives .................. 172
En rsum ...................................................... 182
8. Donnes distantes ......................................... 185
Section 1 : application
browserAJAXAccess ..................................... 186
Section 2 : utilisation
de ServerAccessObject .................................. 188
Section 3 : ServerAccessObject ..................... 193
Section 4 : fonctions de contrle
de la scurit .................................................. 203
En rsum ...................................................... 204
A. Introduction JSON ................................... 205
Section 1 : les fondamentaux ......................... 205
Section 2 : une API JavaScript pour JSON .... 208
En rsum ...................................................... 211
B. Plan de dveloppement
pour QuickConnectFamily ........................ 213
C. Plan de dveloppement
pour PhoneGap .......................................... 219
Index .................................................................. 223
iPhone Livre Page VI Vendredi, 30. octobre 2009 12:04 12
Prface
Cet ouvrage explique comment crer un nouveau type dapplications pour liPhone : les
applications hybrides crites en HTML, CSS et JavaScript. Ce sont des applications auto-
nomes qui sexcutent sur liPhone comme des applications normales, mais sans que les
chiers requis rsident sur un serveur Internet.
La cration dapplications hybrides pour liPhone permet de rduire le temps de dvelop-
pement et dapprentissage, car il nest plus ncessaire de se former Objective-C ou de
matriser les frameworks Cocoa.
Outils pour le dveloppement dapplications
hybrides
Dans ce livre, nous tudierons les deux paquetages logiciels JavaScript open-source les
plus utiliss dans le dveloppement dapplications pour liPhone et liPod Touch : Quick-
ConnectiPhone et PhoneGap. Ils permettent de construire des applications JavaScript qui
accdent aux fonctionnalits natives de lappareil, comme le vibreur, les informations de loca-
lisation GPS, lacclromtre, etc., sans crire une seule ligne de code Objective-C ou Cocoa.
QuickConnectiPhone (http://quickconnect.pbwiki.com) expose le fonctionnement natif
de lappareil et propose un framework complet de haut niveau pour le dveloppement.
Il rduit normment le temps de mise sur le march dune application, car le code glue
quil faut normalement crire en Objective-C, Cocoa et JavaScript est fourni par le
framework. Mieux encore, aucun serveur distant nest requis pour hberger les chiers
JavaScript, HTML et CSS.
iPhone Livre Page 1 Vendredi, 30. octobre 2009 12:04 12
2 Dveloppez des applications pour liPhone
Le second paquetage, PhoneGap (http://phonegap.com), expose un nombre moindre de
comportements natifs et se prsente sous la forme dune bibliothque, non dun framework
complet. En tant que bibliothque, PhoneGap vous permet de construire lapplication
votre manire. En revanche, un serveur distant est obligatoire pour hberger les chiers
1
.
De manire faciliter lapprentissage et la comprhension, les exemples dcrits tout au
long de cet ouvrage sont intressants et importants.
Si votre objectif est de crer des applications installables, si vous avez les connaissances
web requises et si vous souhaitez proposer des solutions dynamiques et convaincantes qui
seront rellement utilises, ce livre vous expliquera comment ces deux paquetages peuvent
rpondre vos besoins.
Le Tableau P.1 compare les possibilits de chaque paquetage au moment de lcriture de
ces lignes.
1. N.d.T. : partir de la version 0.7.3, PhoneGap enregistre les chiers JavaScript, HTML et CSS sur
lappareil, non plus sur un serveur web.
Tableau P.1 : Comparaison des possibilits de QuickConnectiPhone et de PhoneGap
Fonctionnalits QuickConnectiPhone PhoneGap
GPS Oui Oui
Acclromtre Oui Oui
Vibreur Oui Oui
Sons systme Oui Oui
Rseau ad hoc (Bonjour) Oui Non
Rseau par cble de synchronisation Oui Non
Accs une base de donnes par le navigateur Oui Non
Accs une base de donnes intgre Oui Non
Bibliothque de glisser-dposer Oui Non
Enveloppe AJAX Oui Non
Enregistrement/lecture de chiers audio Oui Non
Cartes Google embarques Oui Non
Bibliothque pour tableaux et graphiques Oui Non
iPhone Livre Page 2 Vendredi, 30. octobre 2009 12:04 12
Prface 3
Comment utiliser ce livre
Chaque chapitre est organis en deux parties. La premire explique comment utiliser la
fonctionnalit de QuickConnectiPhone ou de PhoneGap qui permet de raliser une tche
particulire, par exemple obtenir la golocalisation de lappareil. La seconde partie
prsente le code qui se cache derrire lappel JavaScript utilis, ainsi que son fonctionne-
ment. Vous pouvez ainsi dcider du niveau de dtails du code JavaScript et Objective-C
jusquo vous irez.
Le Chapitre 1, "Dvelopper avec Dashcode et Xcode", explique comment utiliser
Dashcode et Xcode avec QuickConnectiPhone et PhoneGap pour crer rapidement des
applications amusantes pour liPhone. Il fournit les bases de lutilisation de Dashcode
et montre comment dplacer votre application Dashcode dans Xcode pour sa compilation
et son excution sur des appareils.
Le Chapitre 2, "Modularit JavaScript", montre comment rduire normment le temps
de mise sur le march dune application en exploitant la modularit du framework
QuickConnectiPhone. Il explique comment exploiter les contrleurs frontaux, les
contrleurs dapplication et la rexion JavaScript.
Le Chapitre 3, "Interfaces utilisateur", facilite lacceptation de vos applications par
lApp Store dApple. Il dcrit les meilleures pratiques du dveloppement dapplica-
tions fonctionnelles pour liPhone. Les diffrents types dapplications gnralement
cres pour liPhone sont examins, ainsi que les piges viter.
Le Chapitre 4, "GPS, acclromtre et autres fonctions natives avec QuickConnect-
iPhone", montre comment obtenir des informations du GPS, de lacclromtre et de
lappareil. Il explique galement comment dclencher le vibreur, et lire et enregistrer
des chiers audio. Le framework QuickConnectiPhone est utilis pour accder ces
fonctions de lappareil et pour les employer. Toutes ces possibilits ajoutent vos
applications un ct plaisant.
Le Chapitre 5, "GPS, acclromtre et autres fonctions natives avec PhoneGap",
montre comment obtenir des informations du GPS, de lacclromtre et de lappareil.
Il explique galement comment dclencher le vibreur, et lire et enregistrer des
chiers audio. La bibliothque PhoneGap est utilise pour accder ces fonctions de
lappareil et pour les employer. Toutes ces possibilits ajoutent vos applications un
ct plaisant.
Le Chapitre 6, "Cartes Google", dcrit lintgration dune carte Google une applica-
tion en utilisant QuickConnectiPhone. Il sagit de lune des fonctionnalits les plus
demandes, qui vite aux utilisateurs de passer par lapplication de cartographie !
iPhone Livre Page 3 Vendredi, 30. octobre 2009 12:04 12
4 Dveloppez des applications pour liPhone
Le Chapitre 7, "Bases de donnes", explique comment lire et enregistrer des donnes
dans des bases SQLite intgres lapplication dveloppe avec le framework Quick-
ConnectiPhone. Si vous devez accompagner votre nouvelle application dune base de
donnes contenant un jeu de donnes prdni, lisez ce chapitre.
Le Chapitre 8, "Donnes distantes", montre comment accder facilement des
donnes disponibles sur des serveurs et/ou des services distants depuis votre applica-
tion en utilisant une enveloppe qui permet dextraire des informations depuis
nimporte quel lieu. Par exemple, vous pouvez rcuprer des donnes partir dun blog
et les fusionner dans un ux Twitter. Grce au module daccs aux donnes distantes
de QuickConnectiPhone, rien nest plus facile.
Ce livre comprend galement trois annexes :
LAnnexe A, "Introduction JSON", est une courte introduction JSON (JavaScript
Object Notation). Ce format est trs utilis et constitue la solution la plus simple pour
envoyer des donnes leurs destinataires.
LAnnexe B, "Plan de dveloppement pour QuickConnectFamily", prsente le futur de
QuickConnectiPhone. Si vous prvoyez de dvelopper des applications pour liPhone
et dautres plates-formes, comme les tlphones Android de Google, les tlphones de
Nokia, les Blackberry et les ordinateurs de bureau sous Mac OS X, Linux et Windows,
vous devez lire cette annexe.
LAnnexe C, "Plan de dveloppement pour PhoneGap", prsente le futur de Phone-
Gap. Si vous envisagez de crer des applications pour liPhone et dautres plates-
formes, comme les tlphones Android de Google, les tlphones de Nokia, les Black-
berry et les ordinateurs de bureau sous Mac OS X, Linux et Windows, vous devez
lire cette annexe.
Code des exemples
Les chiers des exemples de code sont disponibles depuis le site web Pearson (http://
www.pearson.fr), en suivant le lien Codes sources sur la page ddie ce livre. Les
dernires versions de ces exemples, en anglais, sont fournies dans le paquetage de Quick-
ConnectiPhone et dans le modle dapplication PhoneGap. Dans cet ouvrage, les commen-
taires ont t traduits an de faciliter la lecture, mais certains seront invitablement en
anglais car gnrs par les frameworks.
iPhone Livre Page 4 Vendredi, 30. octobre 2009 12:04 12
Prface 5
Ressources en ligne
Le dveloppement de QuickConnectiPhone et de PhoneGap est en cours et les volutions
sont rapides. Pour connatre les nouvelles fonctions et les nouvelles possibilits, et pour en
savoir plus, consultez les liens suivants.
QuickConnectiPhone
tlchargement du framework et de plusieurs exemples (http://sourceforge.net/
projects/quickconnect/) ;
blog concernant le dveloppement (http://tetontech.wordpress.com) ;
wiki ddi au framework (http://quickconnect.pbwiki.com/FrontPage) ;
groupe Google (http://groups.google.com/group/quickconnectiPhone/) ;
service Twitter (http://twitter.com/quickconnect).
PhoneGap
tlchargement du framework et de plusieurs exemples (http://sourceforge.net/
projects/phonegapinstall/) ;
site web de la bibliothque (http://www.phonegap.com/) ;
wiki ddi la bibliothque (http://phonegap.pbwiki.com/) ;
groupe Google (http://groups.google.com/group/phonegap) ;
service Twitter (http://twitter.com/phonegap).
Prrequis
Pour rellement proter du contenu de cet ouvrage, vous devez possder des connaissances
de base en HTML, CSS et JavaScript. Si vous avez dj cr des pages web laide de
ces technologies, vous tes prt crer des applications pour liPhone. Si vous avez besoin
daide avec Objective-C, que ce soit pour QuickConnectiPhone ou PhoneGap, elle vous
sera fournie. Ce livre ne constitue pas une introduction Objective-C ni son utilisation
dans le dveloppement dapplications pour liPhone.
Vous devez tlcharger et installer les outils Xcode dApple disponibles sur le site web
du dveloppeur pour liPhone (http://developer.apple.com/iphone). Ils ncessitent
Mac OS X 10.5 ou ultrieur et une machine Intel.
iPhone Livre Page 5 Vendredi, 30. octobre 2009 12:04 12
6 Dveloppez des applications pour liPhone
Bien que cela ne soit pas obligatoire, il est prfrable de disposer dun iPhone ou dun
iPod Touch an de tester et dexcuter les applications sur ces appareils.
Remerciements
Je souhaite remercier tout particulirement Daniel Barney pour avoir travaill sur le code
dintgration des cartes Google. Merci galement mes collgues du dpartement des
technologies de linformation de luniversit Brigham Young, Idaho, pour leur attention et
leurs suggestions.
propos de lauteur
Lee S. Barney (Rexburg, Idaho) est professeur dans le dpartement des technologies de
linformation au Business and Communication College de luniversit Brigham Young,
dans lIdaho. Il a travaill comme directeur des technologies de linformation pour
@HomeSoftware, une socit qui dveloppe des applications web mobiles de planication
pour le march des soins mdicaux domicile. Avant cela, il a t pendant plus de sept ans
programmeur, ingnieur logiciel senior, directeur du service de la abilit des chefs de
projet pour AutoSimulations, Inc., le principal fournisseur de logiciels de planication
pour lindustrie des semi-conducteurs. Il est lauteur du livre Oracle Database AJAX &
PHP Web Application Development.
Contacter lauteur
Pour contacter lauteur par courrier lectronique, utilisez ladresse quickconnect-
family@gmail.com. Pour dautres mthodes de contact, utilisez les liens Twitter, wiki et
groupe Google donns prcdemment.
iPhone Livre Page 6 Vendredi, 30. octobre 2009 12:04 12
1
Dvelopper avec Dashcode
et Xcode
Utiliss ensemble, Dashcode et Xcode offrent la puissance et la simplicit dutilisation
ncessaires la cration dapplications hybrides uniques et passionnantes pour liPhone.
Puisque ces deux outils fournissent des modles personnaliss adapts aux applications
hybrides pour liPhone, vous navez pas besoin de crer votre propre enveloppe en Objec-
tive-C. Les trois premires sections de ce chapitre expliquent comment utiliser les
modles dapplication existants pour Dashcode et Xcode. Grce ces modles, vous
pouvez crer rapidement des applications hybrides pour liPhone. Les quatre dernires
sections introduisent les bases dObjective-C et la manire de structurer une application
iPhone en Objective-C dans les deux outils les plus employs QuickConnectiPhone et
PhoneGap.
iPhone Livre Page 7 Vendredi, 30. octobre 2009 12:04 12
8 Dveloppez des applications pour liPhone
Section 1 : utiliser Dashcode et le modle
QuickConnect
Dans les applications hybrides pour liPhone, une grande partie de linterface utilisateur et
des interactions est cre avec HTML, JavaScript et CSS. Par consquent, le dveloppe-
ment et le dbogage se font principalement dans Dashcode. Les possibilits et la facilit
demploi de loutil de construction dinterfaces par glisser-dposer fourni par Dashcode sont
uniques. Dashcode est utilis pour crer une grande partie de lapplication et sert galement
la tester en employant le simulateur diPhone et les outils de dbogage intgrs.
Puisque les applications hybrides pour liPhone ont beaucoup de code en commun, la
cration dun modle contenant ce code permet dviter son criture ou son importation
chaque dbut dun nouveau projet. Nous reviendrons sur ce code commun au Chapitre 2.
Pour tlcharger QuickConnectiPhone, allez sur la page http://sourceforge.net/projects/
quickconnect. Le paquetage obtenu inclut un modle Dashcode qui vous aidera crer
des applications hybrides pour liPhone. Le programme dinstallation de QuickConnect-
Family ajoute ce modle Dashcode. Malheureusement, au moment de lcriture de ces
lignes, les auteurs de PhoneGap ne proposent pas de modle Dashcode.
Aprs avoir excut le programme dinstallation de QuickConnectFamily et avoir lanc
Dashcode, le modle QuickConnectiPhone est propos la n de la liste afche dans la
rubrique Dashboard Widget. En double-cliquant sur licne QuickConnectiPhone, vous
arrivez directement lcran principal de Dashcode, avec une interface utilisateur vierge
(voir Figure 1.1).
Pour comprendre les chiers inclus dans le framework et les utiliser facilement, nous
allons crer une premire interface utilisateur simple avec Dashcode et la dployer sur
liPhone avec Xcode. Elle sera constitue uniquement dun bouton et dune zone de texte.
Lors dun clic sur le bouton, la zone de texte afchera : "Vous lavez fait !"
Applications hybrides et bote dalerte
Les dveloppeurs qui ont lhabitude de coder en JavaScript utilisent souvent une bote
dalerte pour dboguer lapplication ou afcher des messages lutilisateur. La fonction
JavaScript alert est en ralit un appel du code natif dans le navigateur, non une possi-
bilit du moteur JavaScript.
Ce fonctionnement nest pas mis en uvre dans les applications QuickConnectiPhone car
lutilisation des botes de dialogue est contraire aux standards tablis par Apple pour
linterface utilisateur des applications iPhone. Pour le dbogage, vous pouvez vous servir
du dbogueur de Dashcode. Si vous dplacez votre application dans Xcode, vous pouvez
employer la fonction debug pour afcher des messages dans la console de Xcode.
iPhone Livre Page 8 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 9
PhoneGap propose une bote dalerte, mais pas la fonction de dbogage de Xcode.
Pour afcher des informations importantes, ajoutez-les dans un lment HTML <div>, ou
autre, quel que soit loutil que vous utilisez.
Noubliez pas : vous devez tre attentif, sans tre alarmiste.
Avant de crer linterface utilisateur, vriez que la fentre Bibliothque est ouverte.
Ensuite, recherchez llment Texte dans la bibliothque des parties et faites-le glisser sur
lcran vierge de lapplication. Une nouvelle zone de texte, contenant le mot "Texte",
safche en haut de linterface. Par dfaut, la taille de cette zone de texte est xe 100 %.
Dashcode a insr dynamiquement une balise HTML <div> dans le chier index.html de
lapplication, ainsi que du code JavaScript pour la complter par le texte, la couleur
darrire-plan et les autres caractristiques que vous choisissez.
Pour notre exemple, nous souhaitons xer lidentiant de la balise de texte display et
effacer son contenu. Pour cela, nous allons employer linspecteur des lments de linterface.
Figure 1.1
Le modle QuickConnectiPhone est utilis dans Dashcode. Le contenu de la bibliothque standard
est afch.
iPhone Livre Page 9 Vendredi, 30. octobre 2009 12:04 12
10 Dveloppez des applications pour liPhone
Cliquez sur licne Inspecteur dans la barre suprieure de Dashcode de manire activer
la bote de dialogue correspondante. Slectionnez longlet Attributs (de couleur rouge et
blanc) dans le coin suprieur gauche de linspecteur, xez le champ Identifiant
display et effacez le contenu du champ tiquette.
Ajoutez un bouton poussoir linterface, en faisant glisser et en dposant la partie corres-
pondante sous la zone de texte. Linspecteur afche prsent les informations concernant
ce bouton, non plus celles du champ de texte. Ouvrez longlet Comportements en
cliquant sur le cube bleu dans le coin suprieur droit de linspecteur. Il permet de dnir
les fonctions JavaScript qui serviront de gestionnaires pour les types dvnements
lists. Vous remarquerez que plusieurs des vnements standard de la souris sont absents.
Ils ont t remplacs par ongesturestart, ongesturechange et ongestureend. Saisissez
changeText dans la colonne Gestionnaires de lvnement onclick. Cette opration
ajoute une fonction changeText dans le chier main.js et afche son contenu lcran
an que vous puissiez saisir le code excut lorsque lvnement onclick est dclench.
Pour notre exemple simple, placez le code suivant dans la fonction changeText :
document.getElementById(display).innerHTML = "Vous lavez fait!";
Notre application peut prsent tre excute dans le simulateur diPhone
1
. Cliquez sur
licne Excuter dans le coin suprieur gauche de Dashcode. Le simulateur est alors
dmarr et lapplication y est excute (voir Figure 1.2).
Puisque lapplication est dbogue et termine, vous pouvez dplacer le code dans Xcode
en vue de son dploiement sous forme dune application installable.
Tout dabord, vous devez utiliser Dashcode pour dployer lapplication actuelle. En effet,
le code est cach dans le projet Dashcode et contient des directives que seul Dashcode
peut comprendre. Cliquez sur licne Partager dans la partie gauche de Dashcode an
dafcher lcran de dploiement. Vous pourrez ainsi enregistrer lintgralit des chiers
HTML, CSS et JavaScript sur le disque de manire les inclure dans votre application.
Dans le champ Chemin, saisissez un nom pour le nouveau rpertoire dans lequel seront
placs ces chiers. Ils peuvent prsent tre imports dans Xcode. La Figure 1.3 montre
lcran de dploiement.
Pour de plus amples informations concernant les chiers JavaScript inclus dans ce modle
et leur utilisation pour simplier la cration dune application, consultez le Chapitre 2.
1. N.d.T. : par dfaut, le simulateur diPhone est normalement congur pour la langue anglaise. Pour le
passer en franais, utilisez lapplication Rglages.
iPhone Livre Page 10 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 11
Figure 1.2
Lapplication en cours
dexcution dans le
simulateur diPhone
de Dashcode.
Figure 1.3
Lcran de dploiement afche lapplication termine en cours de dploiement vers le rpertoire
Exemple1_Chapitre1.
iPhone Livre Page 11 Vendredi, 30. octobre 2009 12:04 12
12 Dveloppez des applications pour liPhone
Section 2 : utiliser Xcode et le modle QuickConnect
Puisque vous avez excut le programme dinstallation de QuickConnectFamily, le
modle Xcode pour les applications QuickConnectiPhone a t install. Nous allons
lutiliser pour crer le projet Xcode de notre application hybride QuickConnectiPhone.
Cette section dcrit les diffrentes tapes de la procdure. Le wiki QuickConnectFamily
propose une vido qui dcrit cette procdure (http://quickconnect.pbwiki.com/Moving-
Dashcode-projects-to-Xcode).
Commencez par slectionner File > NewProject, puis iPhone OS > Applications.
Double-cliquez sur licne QuickConnect iPhone Application et nommez le projet
(le rpertoire correspondant est cr sur le disque dur). Xcode cre un projet qui
comprend les chiers Objective-C ncessaires lexcution de lapplication JavaScript
directement sur lappareil, sans disposer dun accs rseau ou dun accs Internet. Dans le
groupe Resources de lapplication, vous trouverez un ensemble de chiers HTML, CSS
et JavaScript.
Lun de ces chiers se nomme index.html. Il contient tout le code HTML, CSS et Java-
Script dun exemple dapplication prte fonctionner. La Figure 1.4 montre lexcution de
cet exemple sur le simulateur sous forme dune application installe. Avant de lessayer,
vous devez prciser Xcode dutiliser le simulateur de liPhone. Pour cela, ouvrez le
menu Project > Set Active SDK, puis choisissez un simulateur dans la liste.
Figure 1.4
Lapplication
QuickConnect par dfaut.
iPhone Livre Page 12 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 13
Pour inclure dans ce projet les chiers crs prcdemment dans Dashcode, commencez
par supprimer les chiers suivants partir du groupe Resources :
index.html ;
main.css ;
main.js ;
les ventuels chiers du sous-groupe Parts ;
les ventuels chiers du sous-groupe Images.
Ensuite, importez les chiers index.html, main.css et main.js de lexemple prcdent. Pour
cela, maintenez enfonce la touche Contrle et cliquez du bouton droit sur le groupe
Resources, puis slectionnez Add > Existing Files. Allez dans le rpertoire dans
lequel vous avez dploy lapplication Dashcode et slectionnez index.html, main.css et
main.js. Vous pouvez copier les chiers dans le projet Xcode ou les utiliser partir de leur
emplacement actuel. Pour cet exemple, cochez la case Copy items into destination
groups folder (if needed).
Copier ou ne pas copier, telle est la question
Cest vous de dcider si vous devez copier les chiers existants ou laisser Xcode utiliser
des rfrences vers ces chiers. Comment prendre votre dcision ? Chaque mthode
prsente des avantages.
Si vous copiez les chiers, le rpertoire du projet est complet et peut tre pass dautres
dveloppeurs sans quils aient besoin de reproduire la structure de rpertoires de la
machine do proviennent les chiers dorigine.
Avec les rfrences, vous pouvez retourner dans Dashcode pour apporter des modica-
tions et exporter ensuite le projet de manire actualiser les chiers. Vous navez pas
besoin de les importer nouveau dans Xcode.
Cliquez ensuite du bouton droit sur le groupe Parts (sil nexiste pas sur le disque dur, il
est afch en rouge et vous devrez le crer avant limportation) et importez les chiers qui
se trouvent dans le dossier Parts. Rptez cette opration pour le groupe Images et le
dossier Images. Lapplication est quasiment prte tre excute.
Puisque des chiers ont t ajouts au groupe Resources, il faut indiquer Xcode quil
doit les inclure dans les ressources de lapplication. Ouvrez la rubrique Targets, puis
dveloppez votre application et Copy Bundle Resources. Vous voyez alors les chiers de
ressources requis par lapplication. Slectionnez les chiers, non les groupes, que vous
iPhone Livre Page 13 Vendredi, 30. octobre 2009 12:04 12
14 Dveloppez des applications pour liPhone
venez dajouter dans votre projet et faites-les glisser dans la liste Copy Bundle Resources.
Ensuite, dveloppez la rubrique Compile Sources et supprimez tous les chiers Java-
Script, car ils ne pourront videmment pas tre compils. Pour cela, maintenez enfonce la
touche Ctrl, cliquez du bouton droit sur chacun deux et slectionnez Delete. Les chiers
sont supprims de la liste des chiers compiler, mais ils ne sont pas retirs du projet ou
du disque.
Puisque Dashcode utilise des rpertoires et que Xcode utilise des groupes, vous devez
apporter deux autres modications avant de pouvoir excuter lapplication. La premire
concerne la section <head> du chier index.html. Puisque les chiers JavaScript et les
autres chiers rfrencs sont placs dans le rpertoire des ressources de lapplication
nale, les rfrences aux rpertoires Parts et QCiPhone doivent tre supprimes. Par
exemple, avant la suppression des rfrences, voici laspect dune balise <script> :
<script type="text/JavaScript" src="Parts/utilities.js" charset="utf-8"></script>
Elle doit devenir la suivante :
<script type="text/JavaScript" src="utilities.js" charset="utf-8"></script>
Puisque des images sont utilises pour les boutons et autres lments crs dans Dash-
code, vous devez galement retrouver les instances de la chane Images/ dans lensemble
du projet et les remplacer par une chane vide. Cette opration est trs facile en ouvrant le
menu Edit, en choisissant Find > Find in Project et en recherchant Images/. La
Figure 1.5 montre les rsultats de la recherche dans notre exemple, avant la modication
du chier PushButton.js.
Vous pouvez prsent installer et excuter votre application en slectionnant licne
Build and Go, qui se trouve dans la barre suprieure de lapplication Xcode. Si vous rece-
vez le message derreur "No provisioned iPhone OS device is connected", vous pouvez
installer et excuter lapplication dans le simulateur la place de votre appareil. Pour
cela, cliquez sur Succeeded dans le coin infrieur droit de la fentre Xcode, ouvrez la
liste Device | Debug et slectionnez une version du simulateur. Notez que vous
pouvez galement choisir Release ou Debug dans cette liste droulante. Cette bote de
dialogue est frquemment utilise au cours des dveloppements pour effectuer ce type de
modication. La Figure 1.6 montre lapplication installe et en cours dexcution dans le
simulateur.
Flicitations, vous venez de terminer votre premire application hybride pour liPhone.
iPhone Livre Page 14 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 15
Figure 1.5
Lcran de recherche montre les rsultats de la recherche de la chane Images/ sur lensemble du projet.
Figure 1.6
Lapplication
Exemple2_Chapitre1 est
installe et sexcute sur
le simulateur diPhone.
iPhone Livre Page 15 Vendredi, 30. octobre 2009 12:04 12
16 Dveloppez des applications pour liPhone
Approvisionnement
Lapprovisionnement (provisioning) est un processus en plusieurs tapes que vous, ou
votre reprsentant, devez excuter pour que vous puissiez installer et excuter votre
application sur un iPhone.
Pour prparer votre iPhone, vous devez tre membre de lADC (Apple Developer Connec-
tion) et tre abonn au Program Portal. Si vous faites partie dune quipe, lapprovision-
nement a sans doute dj t effectu pour vous. Dans ce cas, il vous suft simplement
denvoyer les informations dapprovisionnement votre iPhone.
Le site ADC dtaille la procdure dapprovisionnement. Assurez-vous de raliser toutes les
tapes indiques car toute erreur risque de se solder par un chec qui vous empchera de
tester vos applications sur votre appareil.
Section 3 : les bases dObjective-C
Cette section ne constitue pas un didacticiel dtaill sur Objective-C, pas plus quune
prsentation complte sur la manire demployer ce langage pour dvelopper des applica-
tions pour liPhone. Elle se contente dexpliquer comment les classes Objective-C utilises
dans des modles interagissent et se comportent, an que vous puissiez exploiter ces infor-
mations dans les applications hybrides pour liPhone. Elle suppose que vous ayez une
certaine connaissance des objets, mthodes et attributs. Si vous souhaitez en savoir plus
sur le framework JavaScript ou si vous ntes pas intress par le code Objective-C, vous
pouvez sauter la suite de ce chapitre et aller directement au Chapitre 2. Pour de plus
amples informations concernant le dveloppement en Objective-C pour liPhone, consul-
tez louvrage The iPhone Developers Cookbook: Building Applications with the iPhone SDK,
dErica Sadun.
Objective-C est un langage intressant. Les personnes qui possdent une exprience dans
dautres langages, comme JavaScript, PHP, Java ou Perl, risquent de le trouver intimidant
et incomprhensible au premier abord. Toutefois, il mrite dtre tudi de plus prs et pas
uniquement parce quil sagit du langage "natif" de liPhone.
Objective-C est une variante oriente objet de C. Vous pouvez employer tous les aspects
puissants mais dangereux de la programmation en C/C++, comme larithmtique de poin-
teurs, et bncier de mcanismes qui facilitent le travail, comme la gestion automatique
de la mmoire. Dans un langage orient objet, la manire dinstancier un objet est la
premire chose connatre. Si une classe nomme Mammifere est disponible dans le code
iPhone Livre Page 16 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 17
source et si elle possde deux attributs, couleurPoils et tauxButyreux, il est possible de
linstancier en JavaScript de la manire suivante :
var unMammifere = new Mammifere("brun", 0.15);
Vous pourriez penser que cette mthode est normale et attendre des autres langages un
comportement semblable. Dans ce cas, vous risquez de trouver trange linstanciation des
objets en Objective-C. Voici linstanciation quivalant la prcdente en Objective-C :
Mammifere *unMammifere = [[Mammifere alloc] initAvecCouleur: @"brun" etTauxBuryteux:
0.15];
Certaines parties sont comprhensibles, dautres, beaucoup moins. Si vous y rchissez,
alloc a un sens car cest ainsi que de lespace en mmoire RAM est allou lobjet
Mammifere. Mme initAvecCouleur et etTauxBuryteux ont un sens en tant que muta-
teurs ou passeurs des deux paramtres requis. Toutefois, que se passe-t-il rellement et que
signient les crochets ?
Pour toutes les interactions avec les objets et les autres lments qui ne sont pas ncessai-
rement des objets dans dautres langages, Objective-C utilise le passage de messages.
tudions le code suivant :
[Mammifere alloc]
Prcdemment, nous avons suppos que ce fragment de code allouait de lespace en RAM
pour un objet de type Mammifere. Cest effectivement le cas. Les crochets autour de
Mammifere et dalloc indiquent que lobjet applicatif qui reprsente la classe Mammifere
reoit le message alloc. Autrement dit, ce bout de code doit se lire "passer un message
alloc lobjet de classe Mammifere". Le passage du message alloc lobjet de classe
Mammifere conduit au retour dun pointeur sur un nouvel objet Mammifere.
Pointeurs
Les pointeurs sont intressants. Toutefois, de nombreux dveloppeurs en ont peur car ils
ne les comprennent pas ou ne les connaissent pas.
Pour mieux les expliquer, prenons lanalogie suivante. Imaginez une foule immense dans
laquelle se trouvent Anne et Jean. Ces deux personnes se connaissent et Anne sait o Jean
se trouve dans la foule. Vous abordez Anne et lui demandez o est Jean. Anne pointe son
doigt vers Jean et rpond "le voici".
ce moment-l, Anne est un pointeur sur Jean. Si vous considrez un pointeur comme
quelque chose qui sait o un objet se trouve en mmoire, vous avez tout compris.
iPhone Livre Page 17 Vendredi, 30. octobre 2009 12:04 12
18 Dveloppez des applications pour liPhone
Ce nouvel objet Mammifere instanci peut recevoir des messages. Lextrait de code prcdent
contient un autre message pour ce nouvel objet Mammifere.
Ce nouveau message combine initAvecCouleur et etTauxBuryteux. Nous savons que
ces deux parties reprsentent un message car elles sont, avec le nouvel objet Mammifere,
entoures de crochets qui, rappelons-le, signient un passage de message. Les multiples
parties dun message sont spares par des espaces.
Par ailleurs, les diffrentes parties du message et les valeurs correspondantes sont lies par
le caractre deux-points (:). Un seul paramtre peut tre associ chaque partie du
message. Le message pass retourne un pointeur sur le nouvel objet Mammifere allou an
quil puisse tre enregistr localement en vue de son utilisation ultrieure. En Objective-C,
ces indicateurs de messages, quil sagisse dun message une ou plusieurs parties, sont
appels slecteurs car ils dsignent les mthodes de lobjet slectionnes par le compilateur
et excutes.
Revenez au projet Xcode Exemple2_Chapitre1 cr la Section 2. Dans le chier
Exemple2_Chapitre1AppDelegate.m, examinez la mthode applicationDidFinish-
Launching gnre par le modle. Ne vous occupez pas du fonctionnement du code,
simplement du passage de message :
1 - (void)applicationDidFinishLaunching:(UIApplication *)application {
2 // Cette ligne aide au dbogage. Vous pouvez voir exactement o sont places
vos vues.
3 // Si vous voyez du rouge, la fentre est vide. Sinon, utilisez le noir.
4 //window.backgroundColor = [UIColor redColor];
5
6
7 QuickConnectViewController *aBrowserViewController=
[[QuickConnectViewController alloc] init];
8
9 // Ajouter la vue CreateViewController window en tant que vue secondaire.
10 [window addSubview:aBrowserViewController.view];
11
12 [window makeKeyAndVisible];
13 }
La ligne 7 doit vous sembler familire. Elle nimplique aucun mammifre, mais elle utilise
les messages alloc et init que vous avez rencontrs prcdemment. Dans ce cas, un
objet QuickConnectViewController est allou et initialis. Son objet de classe reoit le
message alloc et retourne un pointeur sur le nouvel objet QuickConnectViewController
allou. Celui-ci, au travers de son pointeur, reoit le message init.
Ce message ralise une opration semblable celle du message multipartie initAvecCou-
leur:etTauxBuryteux de Mammifere, mais il est beaucoup plus simple. Il sagit dun
iPhone Livre Page 18 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 19
message en une partie, sans aucun paramtre. Plus loin dans ce chapitre, vous verrez
comment crer des mthodes dinitialisation et dautres mthodes excutes par les objets
lorsquils recevront un message.
La ligne 10 envoie un message window. Ce message addSubView possde un paramtre
qui correspond lattribut view contenu dans lobjet aBrowserViewController.
Vous savez prsent comment instancier un objet, enregistrer localement un pointeur sur
le nouvel objet, comment accder aux attributs dun objet et comment passer aux objets
des messages avec ou sans paramtre. Vous disposez donc des bases dObjective-C nces-
saires pour comprendre le code des modles QuickConnectiPhone et PhoneGap. Nous
allons prsent voir comment les applications Objective-C sont assembles.
Section 4 : structure Objective-C dune application
QuickConnectiPhone
Bien que cette section prsente du code issu du modle dapplication QuickConnecti-
Phone, une approche quivalente est employe par PhoneGap et toutes les autres mises en
uvre des applications hybrides. Vous pouvez utiliser lune de ces implmentations ou, en
les tudiant, crer votre propre version.
Imaginez que vous disposiez dun grand nombre de parts dans une entreprise prospre.
Imaginez quune runion des actionnaires ait lieu pour lire le prsident du conseil
dadministration, mais que vous ne puissiez pas y participer en raison de vos vacances
Tahiti. Comment pouvez-vous nanmoins voter ?
Si vous donnez pouvoir une autre personne pour voter votre place, elle devient votre
mandataire. En tant que mandataire, elle est pleinement autorise agir pour votre compte
lors de la runion. Votre mandataire peut donc tre appel votre dlgu. Ce dlgu vous
considre comme le mandant car vous tes lactionnaire rel. La Figure 1.7 illustre ces
relations. Les applications Objective-C pour liPhone se fondent sur ces relations
mandant-dlgu entre des objets, dont lun reprsente le mandant et lautre, le dlgu.
Les relations de type mandant-dlgu sont trs rpandues dans les applications Objec-
tive-C pour liPhone. Voici celles qui nous intressent principalement :
UIApplication/UIApplicationDelegate ;
Figure 1.7
Une reprsentation
graphique de la relation
mandant-dlgu.
Mandant
Mandataire/
dlgu
a un
a un
iPhone Livre Page 19 Vendredi, 30. octobre 2009 12:04 12
20 Dveloppez des applications pour liPhone
UIWebView/UIWebViewDelegate ;
UIAccelerometer/UIAccelerometerDelegate.
ce stade, vous devez comprendre que limplmentation des mthodes du protocole pour
ces dlgus indique lapplication, la vue ou lacclromtre que vous souhaitez que
la prise en charge dvnements spciques se fasse par le dlgu la place de la
mthode. Chaque mthode du protocole est associe un vnement.
Protocoles
Un protocole est un ensemble de mthodes qui peuvent tre ajoutes une classe an
quelle rponde certains messages.
En ayant ces concepts de mandant-dlgu lesprit, examinons une classe qui joue le rle
de dlgu. Le chier den-tte de la classe Exemple2_Chapitre1AppDelegate a t
gnr par le modle QuickConnectiPhone lorsque que vous avez cr lapplication
Exemple2_Chapitre1 la Section 2. Il est donn ci-aprs.
Les chiers den-tte Objective-C, ceux qui se terminent par .h, dclarent des classes.
Examinez celui de Exemple2_Chapitre1AppDelegate, mais sans vous occuper du chier
dimplmentation :
1 // Exemple2_Chapitre1AppDelegate.h
2 #import <UIKit/UIKit.h>
3 #import "QuickConnectViewController.h"
4
5 @interface Exemple2_Chapitre1AppDelegate: NSObject <UIApplicationDelegate> {
6 IBOutlet UIWindow *window;
7 QuickConnectViewController *browserViewController;
8 }
9
10 @property (nonatomic, retain) UIWindow *window;
11 @property (nonatomic, retain) QuickConnectViewController *browser
ViewController;
12
13 @end
Examinez la ligne 5. Si vous connaissez Java, ne vous laissez pas induire en erreur par
lindicateur @interface. Il ne signie pas que cette classe quivaille une interface Java.
Il signie que ce chier contient la dnition de linterface de la classe. Ce chier den-
tte dclare les attributs de la classe Exemple2_Chapitre1AppDelegate, la manire dy
iPhone Livre Page 20 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 21
accder et les mthodes qui doivent tre mises en uvre dans le chier dimplmentation.
Cette classe ne possde aucune mthode en propre.
Sil ne sagit pas dune dclaration dinterface la manire de Java, quel est donc le rle
de la ligne 5 ? Elle dclare le nom de la classe, Exemple2_Chapitre1AppDelegate, et
utilise le caractre deux-points pour indiquer quelle drive de la classe NSObject. La
classe est donc un NSObject et peut accepter tout message dni par NSObject. Si vous
examinez la classe NSObject dans la documentation de lAPI (accessible au travers du
menu daide de Xcode), vous pouvez constater quelle possde une mthode description.
Par consquent, puisque Exemple2_Chapitre1AppDelegate hrite de NSObject, elle
possde galement une mthode description.
Aprs la dclaration dhritage de NSObject, vous voyez <UIApplicationDelegate>.
Cela indique la classe Exemple2_Chapitre1AppDelegate quelle se comporte comme
un dlgu de votre application et vous permet de mettre en uvre les mthodes des
messages du protocole UIApplicationDelegate dans le chier dimplmentation de
Exemple2_Chapitre1AppDelegate. Lune des mthodes de ce protocole se nomme
applicationDidFinishLaunching.
Cette mthode est invoque lorsque le chargement de lapplication est termin et quelle
est prte tre excute. La mthode permet de personnaliser lapplication ou de demander
des informations supplmentaires lutilisateur.
Dans le code suivant, la ligne 13 contient la dnition de applicationDidFinish-
Launching donne par QuickConnectiPhone dans le chier dimplmentation. Elle
commence par un signe moins (-) qui indique quil sagit dune mthode dobjet. (void)
signie que la mthode ne retourne aucune valeur, tandis que :(UIApplication
*)application indique quelle attend un paramtre de type UIApplication.
1 //
2 // Exemple2_Chapitre1AppDelegate.m
3 // Exemple2_Chapitre1
4 //
5
6 #import "Exemple2_Chapitre1AppDelegate.h"
7 @implementation Exemple2_Chapitre1AppDelegate
8
9 @synthesize window;
10 @synthesize browserViewController;
11
12
13 - (void)applicationDidFinishLaunching:(UIApplication *)application {
14 // Cette ligne aide au dbogage. Vous pouvez voir exactement o sont places
vos vues.
iPhone Livre Page 21 Vendredi, 30. octobre 2009 12:04 12
22 Dveloppez des applications pour liPhone
15 // Si vous voyez du rouge, la fentre est vide. Sinon, utilisez le noir.
16 //window.backgroundColor = [UIColor redColor];
17
18
19 QuickConnectViewController *aBrowserViewController=
[[QuickConnectViewController alloc] init];
20
21 // Ajouter la vue CreateViewController window en tant que vue secondaire.
22 [window addSubview:aBrowserViewController.view];
23
24 [window makeKeyAndVisible];
25 }
Puisquelle fait partie de la classe dlgue de votre application, cette mthode applica-
tionDidFinishLaunching est invoque automatiquement lorsque le chargement de
lapplication est termin. Cest pourquoi elle peut tre utilise pour instancier dautres
lments ncessaires lapplication. Dans cet exemple, vous pouvez voir la ligne 19
lallocation et linitialisation dune autre classe, QuickConnectViewController, ajoute
lapplication par le modle.
Les applications pour liPhone utilisent des vues, et nimporte quel objet UIWindow ou
UIView peut contenir des objets UIView. Par consquent, il est possible davoir des vues
imbriques. Cependant, cette conception est dconseille dans les applications pour
liPhone. la place de cette approche hirarchique, la plupart des dveloppeurs choisis-
sent dchanger une vue secondaire par une autre un niveau aussi lev que possible,
selon les besoins de lutilisateur.
Le remplacement des vues secondaires rduit la complexit de la structure des vues de
lapplication. Par chance, le modle utilis pour crer lapplication a plac le nombre
de vues imbriques adquat pour que le contenu web puisse tre afch. En ralit,
comme nous le verrons plus loin, il a insr une vue secondaire web dans la vue qui a t
ajoute lobjet window.
Un attribut de la classe QuickConnectViewController correspond lobjet de vue qui
afche le contenu dans la fentre de lapplication. Cet attribut doit tre ajout la fentre
principale en tant que vue secondaire, une opration effectue la ligne 22.
En plus de possder la vue du contenu, la classe QuickConnectViewController joue
galement le rle de dlgu pour la localisation GPS, lacclromtre, la vue web et
dautres types dvnements.
iPhone Livre Page 22 Vendredi, 30. octobre 2009 12:04 12
Chapitre 1 Dvelopper avec Dashcode et Xcode 23
Section 5 : structure Objective-C dune application
PhoneGap
En tant quapplications pour liPhone, les applications PhoneGap respectent galement
la mme structure mandant-dlgu que les applications QuickConnectiPhone (pour de
plus amples informations, consultez la Section 4). La classe dlgue que vous devez
comprendre se nomme GlassAppDelegate. Tout comme la classe Exemple2_Chapi-
tre1AppDelegate examine la Section 4, elle possde un chier de dnition, GlassAp-
pDelegate.h, et un chier dimplmentation, GlassAppDelegate.m.
La classe GlassAppDelegate des applications PhoneGap nest pas seulement un dlgu
de lapplication, mais galement un dlgu pour tous les types de comportements. Les
chiers .h et .m sont donc beaucoup plus complexes.
Dans le code suivant, vous constatez que la classe GlassAppDelegate est un dlgu pour
lafchage WebView, le gestionnaire de localisation GPS, lacclromtre et autres. En
effet, ces dlgus sont prsents sous forme dune liste dans la dclaration de linterface,
qui dbute la ligne 16.
1 #import <UIKit/UIKit.h>
2 #import <CoreLocation/CoreLocation.h>
3 #import <UIKit/UINavigationController.h>
4
5 #import "Vibrate.h"
6 #import "Location.h"
7 #import "Device.h"
8 #import "Sound.h"
9 #import "Contacts.h"
10
11
12 @class GlassViewController;
13 @class Sound;
14 @class Contacts;
15
16 @interface GlassAppDelegate: NSObject <
17 UIApplicationDelegate,
18 UIWebViewDelegate,
19 CLLocationManagerDelegate,
20 UIAccelerometerDelegate,
21 UIImagePickerControllerDelegate,
22 UIPickerViewDelegate,
23 UINavigationControllerDelegate
24 >
25 {
iPhone Livre Page 23 Vendredi, 30. octobre 2009 12:04 12
24 Dveloppez des applications pour liPhone
26
27
28 IBOutlet UIWindow *window;
29 IBOutlet GlassViewController *viewController;
30 IBOutlet UIWebView *webView;
31 IBOutlet UIImageView *imageView;
32 IBOutlet UIActivityIndicatorView *activityView;
33
34 CLLocationManager *locationManager;
35 CLLocation *lastKnownLocation;
36
37 UIImagePickerController *imagePickerController;
38
39 NSURLConnection *callBackConnection;
40 Sound *sound;
41 Contacts *contacts;
42 NSURL* appURL;
43 }
44
45 @property (nonatomic, retain) CLLocation *lastKnownLocation;
46 @property (nonatomic, retain) UIWindow *window;
47 @property (nonatomic, retain) GlassViewController *viewController;
48 @property (nonatomic, retain) UIImagePickerController
49 *imagePickerController;
50
51 - (void) imagePickerController:(UIImagePickerController *)picker
52 didFinishPickingImage:(UIImage *)image2 editingInfo:(NSDictionary
53 *)editingInfo;
54 - (void) imagePickerControllerDidCancel:(UIImagePickerController
55 *)picker;
56 @end
Bien que la classe GlassAppDelegate soit plus complexe, elle est comparable la classe
Exemple2_Chapitre1AppDelegate de la section prcdente. Elle joue le rle de dlgu
pour lapplication et dautres types dvnements, alors que limplmentation Quick-
ConnectiPhone utilise la classe QuickConnectViewController comme dlgu pour tous
les vnements autres que ceux du dlgu de lapplication.
La mthode applicationDidFinishLaunching est comparable celle de la classe
Exemple2_Chapitre1AppDelegate. Pour que ce soit plus clair, seule une partie du code
source de la mthode applicationDidFinishLaunching de PhoneGap est donne ci-
aprs. Le code restant sera tudi en dtail la Section 8 et au Chapitre 7.
1 -(void)applicationDidFinishLaunching:
...
2 webView.delegate = self;
iPhone Livre Page 24 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 1 Dvelopper avec Dashcode et Xcode 25
...
3 [window addSubview:viewController.view];
...
4 }
La ligne 2 est intressante. linstar de la version de Exemple2_Chapitre1AppDelegate
tudie la Section 4, elle affecte un objet UIWebView comme vue secondaire de la fentre
principale. Autrement dit, lobjet UIWebView est utilis comme zone dafchage pour
lapplication.
Puisque vous connaissez prsent limplmentation de la principale mthode dlgue de
lapplication dans QuickConnectiPhone et PhoneGap, vous tes prt comprendre lutili-
sation de la classe UIWebView pour afcher et excuter une application JavaScript.
Section 6 : embarquer du contenu web
avec QuickConnectiPhone
Pour afcher du contenu web, par exemple des applications JavaScript ou de simples
pages web, dans votre application, vous devez utiliser la classe UIWebView. Toutes les
mises en uvre des applications hybrides, que ce soit avec QuickConnectiPhone ou
PhoneGap, emploient cette classe. Si vous souhaitez vous amuser avec les polices de
caractres dans une application, par exemple plusieurs polices, dans diffrentes tailles et
couleurs, vous devez utiliser UIWebView, moins que vous ne souhaitiez dessiner le texte
vous-mme. La classe UIWebView est simple dutilisation car elle sait comment interprter
le contenu HTML et CSS, ainsi que le code JavaScript. Cela permet de crer facilement
des prsentations textuelles, ou dautres types, complexes.
UIWebView est en ralit une enveloppe autour du moteur de rendu WebKit utilis dans le
navigateur Safari, dans Adobe Air, dans Android, dans les tlphones Nokia et dans
plusieurs autres applications, notamment celles livres avec Mac OS X, comme Mail.
Dashcode est galement un grand utilisateur du moteur WebKit.
Nous lavons mentionn dans les deux sections prcdentes, pour quune vue web soit
incluse dans une application lobjet UIWebView doit tre ajout comme vue secondaire
dune autre vue de lapplication. Pour cela, la mthode loadView de la classe Quick-
ConnectViewController est invoque.
La mthode loadView contient diffrents lments qui permettent dexprimer des compor-
tements dans une application JavaScript. Par exemple, elle fournit le code qui redimen-
sionne linterface utilisateur de lapplication de manire ladapter la taille de lcran.
iPhone Livre Page 25 Vendredi, 30. octobre 2009 12:04 12
26 Dveloppez des applications pour liPhone
Cette possibilit est dsactive par dfaut, car linterface utilisateur doit tre initialement
conue la taille adquate.
La partie intressante de loadView permet lafchage de linterface conue dans Dash-
code prcdemment dans ce chapitre. Lextrait de code suivant montre comment liPhone
insre ce contenu dans lapplication. Il commence par calculer la taille et le point dorigine
pour lafchage de lobjet UIWebView. Pour cela, il obtient la taille et lemplacement du
cadre dafchage de lapplication.
La variable webFrame, dont le type est une structure CGRect, contient ces informations
obtenues par lenvoi du message applicationFrame lcran principal de lapplication.
La structure CGRect est constitue de deux lments : un CGPoint, nomm origin, qui
reprsente les coordonnes X et Y du point suprieur gauche, et un CGSize, qui reprsente
la taille du rectangle exprimer sous forme dune hauteur et dune largeur :
CGRect webFrame = [[UIScreen mainScreen] applicationFrame];
webFrame.origin.y -= 20.0;
Les coordonnes X et Y, la largeur et la hauteur dun CGRect sont des nombres rels utili-
ss pour enregistrer un nombre de pixels. La seconde ligne du code prcdent montre
comment changer la position verticale courante enregistre dans la variable webFrame.
Elle dcale lorigine vers le haut de vingt pixels. Cette opration est ncessaire pour recou-
vrir un espace laiss vide dans la vue en raison de labsence dune barre doutils en haut de
la fentre dafchage.
Cette barre doutils est visible dans de nombreuses applications standard, comme lappli-
cation Rglages utilise pour congurer liPhone. Elle a t retire des modles an
daugmenter la place disponible sur lcran pour lapplication. Si vous souhaitez disposer
des boutons Suivant et Prcdent proposs par cette barre doutils, vous devez la crer
dans votre application laide de Dashcode.
Aprs avoir enregistr dans la variable webFrame lemplacement et la taille souhaits pour
lafchage du contenu web, elle est utilise pour initialiser un objet UIWebView nomm
aWebView. Les lignes 1 et 2 du code suivant montrent cette opration. Notez quelle
ressemble lallocation de QuickConnectViewController examine prcdemment dans
ce chapitre. Les principales diffrences sont lenvoi du message alloc la classe UIWeb-
View et lenvoi du message initWithFrame lobjet UIWebView qui vient dtre allou,
avec le passage de la structure webFrame qui a t cre et modie dans lextrait de code
prcdent. Lobjet aWebView est positionn et dimensionn conformment aux valeurs
contenues dans webFrame.
1 UIWebView *aWebView = [[UIWebView alloc]
2 initWithFrame:webFrame];
iPhone Livre Page 26 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 1 Dvelopper avec Dashcode et Xcode 27
3 self.webView = aWebView;
4 aWebView.autoresizesSubviews = YES;
5 aWebView.autoresizingMask=(UIViewAutoresizingFlexibleHeight
6 | UIViewAutoresizingFlexibleWidth);
7 // Fixer le dlgu du WebView lui-mme.
8 [aWebView setDelegate:self];
Le nouvel objet UIWebView est enregistr dans lattribut webView de QuickConnectView-
Controller par le code de la ligne 3 an quil soit possible dy accder ultrieurement
depuis dautres mthodes de QuickConnectViewController. Ce point est essentiel pour
lutilisation de lacclromtre, de la localisation GPS et des autres possibilits dcrites au
Chapitre 4.
Les lignes 5 6 illustrent la capacit de lobjet aWebView se redessiner lui-mme. Si
vous le pouvez, vitez lajout de vues secondaires. La ligne 4 stipule que, si aWebView
change de taille, les vues secondaires doivent galement tre redimensionnes. La syntaxe
employe prcise que, si la largeur de aWebView change en raison dune rotation, les vues
secondaires quil contient doivent galement changer de largeur dun facteur identique.
Les lignes 5 et 6 indiquent que la largeur et la hauteur de aWebView seront galement
modies. Lorsque liPhone est bascul, il est frquent de passer la vue courante en mode
paysage, ou de len sortir, et de la redimensionner pour quelle corresponde aux nouvelles
largeur et hauteur de lappareil. Si les lignes 5 et 6 taient retires ou places en commen-
taires, lapplication basculerait toujours, mais la largeur et la hauteur de aWebView ne
seraient pas affectes. Une grande zone vide apparatrait alors droite de lapplication en
mode paysage. Il est rare de trouver des applications qui basculent sans se redimensionner.
La ligne 8 envoie aWebView un message pour lui indiquer que lobjet QuickConnectView-
Controller courant, connu sous le nom self, joue le rle de dlgu de lobjet aWeb-
View. Cela permet dimplmenter plusieurs mthodes facultatives de UIWebViewDelegate
dans la classe QuickConnectViewController. Le Tableau 1.1 recense ces mthodes.
Si vous en avez besoin, vous pouvez ajouter chacune de ces mthodes facultatives la
classe QuickConnectViewController. Le modle a dj ajout webView:shouldStart-
LoadWithRequest, webView:DidStartLoad, webView:DidFinishLoad et webView:did-
FailLoadWithError.
aWebView tant prt, il est temps prsent dindiquer le contenu qui doit tre charg et de
dclencher ce chargement. Pour cela, lemplacement du chier index.html, qui fait partie
des ressources de lapplication, doit tre dtermin. Heureusement, comme le montrent les
lignes 3 et 4, la classe NSBundle qui reprsente lapplication sur le disque dispose dune
mthode nomme pathForResource:ofType.
iPhone Livre Page 27 Vendredi, 30. octobre 2009 12:04 12
28 Dveloppez des applications pour liPhone
La mthode pathForResource:ofType prend deux chanes de caractres en argument. La
premire correspond au nom du chier (la chane "index") et la seconde correspond
lextension du chier (la chane "html"). Cet appel gnre le chemin complet du chier
sur votre machine et lenregistre dans la variable locale filePathString. Ce chemin est
ensuite utilis pour crer un objet qui reprsente une URL vers le chier, puis un objet
aRequest de type NSURLRequest qui reprsente llment charger (voir les lignes 7 et 8).
1 // Dterminer le chemin du fichier index.html dans le
2 // rpertoire Resources.
3 NSString *filePathString = [[NSBundle mainBundle]
4 pathForResource:@"index" ofType:@"html"];
5 // Construire lURL et la requte pour le fichier index.html.
6 NSURL *aURL = [NSURL fileURLWithPath:filePathString];
Tableau 1.1 : LAPI de UIWebView
Signature de la mthode Invocation Paramtres
-(BOOL)webView:(UIWebView *)
webView shouldStartLoad-
WithRequest:(NSURLRequest *)
request navigationType:
(UIWebViewNavigationType)
navigationType
Juste avant que la
vue ne commence
charger le contenu.
webView la vue qui va charger le contenu.
request lemplacement du contenu
charger.
navigationType le type daction utili-
sateur qui dclenche le changement de la
page.
options de UIWebViewNavigationType
LinkClicked, FormSubmitted, Back-
Forward, Reload, FormResubmitted et
Other.
- (void)webViewDidStart-
Load:(UIWebView *) webView
Aprs que la vue a
commenc le char-
gement du contenu.
webView la vue qui charge le contenu.
- (void)webViewDidFinish-
Load:(UIWebView *) webView
Aprs que la vue a
termin avec succs
le chargement du
contenu.
webView la vue qui charge le contenu.
- (void)webView:(UIWebView *)
webView didFailLoadWith-
Error:(NSError *) error
Si la vue na pas
russi charger le
contenu.
webView la vue qui tente de charger le
contenu.
error un objet qui reprsente lerreur
gnre.
iPhone Livre Page 28 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 1 Dvelopper avec Dashcode et Xcode 29
7 NSURLRequest *aRequest = [NSURLRequest
8 requestWithURL:aURL];
9 // Charger le fichier index.html dans la vue web.
10 [aWebView loadRequest:aRequest];
11 // Ajouter la vue web la vue de contenu.
12 [contentView addSubview:aWebView];
la ligne 6, lobjet NSURL reoit le message fileURLWithPath. Puisquun chier est
charg directement depuis le disque, ce message est bien adapt. Cela suft pour les appli-
cations hybrides QuickConnectiPhone, mais, si vous utilisez une autre implmentation et
chargez une page directement depuis le Web, le message doit tre URLWithString, avec
en paramtre une URL complte du type http://www.byui.edu.
Aprs avoir cr lobjet NSURLRequest, le chargement rel de lURL est dclench par
lenvoi du message loadRequest lobjet aWebView de type UIWebView. Lobjet NSUR-
LRequest, reprsent par la variable aRequest, est pass comme seul paramtre de ce
message.
Aprs le chargement de la requte, aWebView est ajout la vue principale de contenu en
lui envoyant le message addSubview avec lobjet UIWebView en paramtre. Si cet appel
nest pas effectu, la page est charge et pleinement active, mais elle nest pas afche.
Section 7 : embarquer du contenu web avec PhoneGap
Contrairement QuickConnectiPhone, PhoneGap dnit lemplacement dun chier
HTML dans la mthode dlgue applicationDidFinishLaunching prsente la
Section 5. Nanmoins, une grande partie de la procdure dafchage du contenu web dans
lapplication reste identique.
Tout comme dans le cas de QuickConnectiPhone dcrit la section prcdente, PhoneGap
doit obtenir un chemin vers un chier dans le paquetage de distribution de lapplication.
Cette fois-ci, le chier se nomme url.txt la place du chier index.html de QuickConnect.
Cette opration est ralise aux lignes 8 12 du code ci-aprs.
Tout dabord, et comme la section prcdente, lobjet NSBundle qui reprsente lapplica-
tion sur le disque est cr. Le message pathForResource lui est ensuite envoy avec les
valeurs url et txt en paramtres. Si le chargement de ce chier russit, la chane de carac-
tres contenue dans le chier url.txt est affecte la variable locale theURLString
(lignes 10 12).
1 NSString * htmlFileName;
2 NSString * urlFileName;
3 htmlFileName = @"index";
iPhone Livre Page 29 Vendredi, 30. octobre 2009 12:04 12
30 Dveloppez des applications pour liPhone
4 urlFileName = @"url";
5 NSString * urlPathString;
6 NSBundle * thisBundle = [NSBundle bundleForClass:
7 [self class]];
8 if (urlPathString = [thisBundle
9 pathForResource:urlFileName ofType:@"txt"]) {
10 NSString * theURLString =
11 [NSString stringWithContentsOfFile:
12 urlPathString];
13 appURL = [NSURL URLWithString:theURLString];
14 [appURL retain];
15 NSURLRequest * aRequest =
16 [NSURLRequest requestWithURL:appURL];
17 [webView loadRequest:aRequest];
18 }
La ligne 13 convertit la chane lue depuis le chier url.txt en un objet NSURL qui sert
crer une requte. Nous lavons vu la section prcdente, cette requte est passe en
paramtre webView en utilisant le message loadRequest.
Par ces deux implmentations du mme comportement, vous pouvez constater que, malgr
leurs lgres diffrences, elles sont quasiment identiques. Toutes les mises en uvre
dapplications hybrides utilisent lapproche suivante :
obtenir une chane dURL ;
crer un NSURL partir de la chane ;
crer un NSURLRequest partir du NSURL ;
utiliser le message loadRequest de UIWebView avec le NSURLRequest en paramtre.
Si vous dcidez dcrire votre propre implmentation, vous devez respecter cette proc-
dure.
En rsum
Pour crer des applications hybrides pour liPhone, vous avez besoin dune petite enve-
loppe Objective-C pour lapplication HTML, CSS et JavaScript. Dashcode est un outil
puissant qui permet de crer rapidement et facilement une application JavaScript dynami-
que, que vous pouvez embarquer en utilisant cette enveloppe. Les modles dapplication
QuickConnectiPhone pour Dashcode et Xcode, ainsi que le modle PhoneGap pour
Xcode, acclrent la cration dune application en incluant dans votre projet le code rp-
titif employ dans toutes les applications hybrides. Comme le montrent les Chapitres 3, 4
et 6 8, les modles Xcode apportent le code Objective-C et JavaScript dont vous avez
iPhone Livre Page 30 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 1 Dvelopper avec Dashcode et Xcode 31
besoin pour crire des applications hybrides qui exploitent les possibilits suivantes en
JavaScript :
PhoneGap
donnes de lacclromtre ;
donnes de localisation GPS ;
vibreur de lappareil.
QuickConnectiPhone
donnes de lacclromtre ;
donnes de localisation GPS ;
vibreur de lappareil ;
sons systme personnaliss ;
enregistrement et lecture audio ;
afchage des dates standard et slecteurs de date et dheure ;
accs aux bases de donnes SQLite livres avec lapplication et celles de UIWeb-
View lors de lexcution de lapplication.
Grce aux modles Dashcode et Xcode, vous pouvez crer des applications pour liPhone
plus rapidement que jamais.
iPhone Livre Page 31 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 32 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
2
Modularit JavaScript
Lorsque lon mentionne JavaScript, deux caractristiques viennent habituellement lesprit :
compatibilit internavigateurs et complexit. Ce chapitre explique comment viter la
complexit dans les applications hybrides pour liPhone et apporte le code source qui permet
de mettre en uvre facilement et rapidement un comportement complexe, sans remettre en
cause la exibilit. Avec les applications hybrides pour liPhone, la compatibilit interna-
vigateurs nest pas un problme car seul le moteur WebKit de Safari est utilis. Il est ainsi
beaucoup plus facile dcrire des applications JavaScript intressantes et amusantes.
Section 1 : modularit
Le concept de modularit existe depuis longtemps, que ce soit dans linformatique ou
dans dautres secteurs industriels. Lessence de la modularit se trouve dans la phrase
"construire partir de pices interchangeables". Si les pices sont des modules rellement
interchangeables, elles doivent tre capables de prendre la place dune autre sans que cela
ncessite, ou presque, une modication des lments qui interagissent avec elles. Dans le
domaine du logiciel, il sagit gnralement dune API commune qui ne change pas.
iPhone Livre Page 33 Vendredi, 30. octobre 2009 12:04 12
34 Dveloppez des applications pour liPhone
Lindustrie du divertissement aurait quelques soucis si chaque lm tait produit sur un
support diffrent, car un systme de lecture diffrent serait alors ncessaire pour chaque
lm. Si un fabricant dautomobiles ne standardisait pas la liaison entre le moteur et la
bote de vitesses, chaque combinaison moteur-bote devrait tre ralise la main. Les
cots monteraient en che et la qualit en ptirait. Dans lindustrie du logiciel, les tentatives
pour crer du code modulaire rutilisable ont t nombreuses. Aujourdhui, elles prennent
la forme de frameworks.
Dnition dun module
Pour quun module existe, il doit prsenter deux caractristiques : cohsion forte et
couplage faible.
Une cohsion forte signie que le module a un rle clairement dni et quil fait le nces-
saire pour le jouer. Il existe pour remplir un objectif, comme grer une activit, et il agit
en ce sens.
Un couplage faible signie que le module ne dpend pas dune connaissance du fonction-
nement interne dautres modules et quaucun autre module ne connat le sien. Pour y
parvenir, il faut crer et utiliser une interface solide.
Lorsque ces deux caractristiques sont l, un module est n.
Ltude des frameworks est intressante. En gnral, un compromis a t fait entre la faci-
lit dutilisation du framework et sa exibilit. Si le dveloppeur du framework nest pas
attentif, il peut obtenir un framework avec lequel la mise en uvre des choses non impor-
tantes est facile, tandis que celle des besoins de lingnieur ou du programmeur est dif-
cile.
Souvent, pour que le framework soit simple demploi et exible, son extensibilit est
sacrie, ce qui est le cas de Ruby on Rails. Ce framework est vraiment gnial, mais il
sadapte mal un environnement dentreprise sans passer par la mise en place dun mat-
riel en cluster. Sa facilit dutilisation est donc rduite et les cots augmentent. Alors,
comment un framework peut-il tre extensible, facile utiliser et exible ? La rponse se
trouve dans une modularit parfaitement applique et tudie.
Bien quils ne soient pas toujours enseigns ou rvls, certains types de modules permet-
tent de faciliter le dveloppement de logiciels. Ces modules, quelque peu secrets, sont
connus sous les termes contrleurs frontaux et contrleurs dapplication.
Les exemples de ce chapitre montrent comment crer et utiliser ces modules et comment
ils permettent de faciliter et dacclrer le dveloppement dune application.
iPhone Livre Page 34 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 35
Section 2 : modularit avec le framework JavaScript
QuickConnect
Dans les modles Dashcode et Xcode, le framework JavaScript est conu pour minimiser
lutilisation du processeur et de la mmoire, tout en restant facile employer. Puisquil est
conu de manire hautement modulaire, chaque composant ralise une chose, la fait bien
et la fait rapidement.
La conception se fonde sur un paradigme de commande-rponse. Lorsque vous envoyez
une commande, les modules excutent les fonctions ncessaires qui lui sont associes. La
Figure 2.1 illustre ce ux de traitement dans une application dont la conception se fonde
sur cette approche. Le traitement commence ltape 1 et se poursuit tout au long du
framework en respectant la numrotation des ches.
Figure 2.1
Le ux de traitement
associ une seule
commande.
Contrleur
frontal
Contrleur
dapplication
Objet d'accs la base de donnes
Fonctions
de contrle
de la validation
Fonctions
de contrle
mtier
Fonctions
de contrle
de l'affichage
Requte
1
4
12
9
10
11
8 5
7 6
2
3
Base de
donnes
SQLite
iPhone Livre Page 35 Vendredi, 30. octobre 2009 12:04 12
36 Dveloppez des applications pour liPhone
Les seuls lments du ux qui ne sont pas dj crs sont les diffrentes fonctions de
contrle propres au fonctionnement de lapplication. Des exemples de ces modules appli-
catifs spciques seront donns tout au long de cet ouvrage.
Lexamen des donnes saisies par lutilisateur se fait par lintermdiaire des fonctions de
contrle de la validation (ValCF, Validation Control Function). Les fonctions de contrle
mtier (BCF, Business Control Function) servent obtenir des donnes partir dune base
de donnes, dun serveur web ou dune autre source, ou enregistrer des donnes. Les
fonctions de contrle de lafchage (VCF, View Control Function) sont employes pour
mettre jour la vue prsente lutilisateur.
Prenons un exemple. Supposons que vous souhaitiez collecter des informations sur lutili-
sateur actuel partir dun formulaire qui comprend un bouton Envoyer. Ces informations
sont ensuite places dans une base de donnes SQLite et lutilisateur est inform du succs
de cet enregistrement. Pour cela, vous devez crer trois fonctions de contrle : une ValCF
pour garantir que les donnes saisies rpondent aux standards dnis par lapplication, une
BCF pour enregistrer les informations dans la base de donnes et une VCF pour dclencher
lafchage des messages de succs.
Toutes les fonctionnalits ne sont pas ncessairement associes aux trois types de fonc-
tions de contrle. Par exemple, une application de jeu na pas forcment besoin dune
ValCF chaque fois que lutilisateur dclenche un comportement.
La Figure 2.1 montre que ces diffrentes fonctions de contrle nont pas besoin de
communiquer lune avec lautre. Les modules du framework sont conus pour un tel fonc-
tionnement. Vous devez simplement crire les fonctions de contrle et les associer des
commandes. Grce cette conception, chaque fonction de contrle comprend seulement
quelques lignes de code et est immdiatement oprationnelle.
Puisque la conception est modulaire, vous pouvez facilement appliquer le concept de divi-
sion du travail. Si vous rpartissez la cration de ces fonctions de contrle au sein dune
quipe, que ce soit en fonction de la commande ou de leur type, les dveloppements
peuvent se faire rapidement en parallle. Pour de plus amples informations concernant ces
fonctions de contrle et leur cration, consultez les Sections 4 et 5.
Lorsquelles sont bien crites, les fonctions de contrle peuvent tre utilises pour
plusieurs commandes. Par exemple, vous pourriez dnir plusieurs commandes pour
actualiser la mme partie de lcran. Avec une telle conception, il est possible dassocier
une VCF qui actualise cette partie de la vue pour toutes les commandes.
Le Tableau 2.1 montre que le contrleur frontal de lapplication reprsente la passerelle au
travers de laquelle toutes les requtes dexcution doivent transiter. En obligeant toutes les
iPhone Livre Page 36 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 37
requtes passer par ce contrleur, il devient beaucoup plus facile de prdnir lordre des
excutions dans lapplication.
Le contrleur frontal est comparable lenceinte qui entoure une ville fortie : il
nexiste quune porte dentre et quune porte de sortie. En limitant les points daccs
possibles la ville, la dfense est plus facile et les citoyens peuvent vivre en meilleure
scurit. Lajout dun contrleur frontal votre application permet de la scuriser plus
facilement.
Dans le framework QuickConnectiPhone, le contrleur frontal est mis en uvre par la
fonction handleRequest. Elle est dnie dans le chier QuickConnect.js, qui, dans
Xcode, fait partie du groupe QCiPhone des ressources dapplication et, dans Dashcode, se
trouve dans le dossier QCiPhone. Si vous examinez le code, vous verrez comment les
fonctions de scurit et dordre dexcution sont mises en uvre.
Lors de son invocation, la fonction handleRequest reoit une commande et un tableau de
paramtres. La commande est obligatoire, contrairement au tableau de paramtres.
Le code suivant, qui correspond aux lignes 17 20 du chier functions.js de lapplication
simpleCalc, illustre linvocation de la fonction handleRequest en rponse une action de
lutilisateur. Dans ce cas, lutilisateur a cliqu sur le bouton qui reprsente laddition (voir
Figure 2.2).
function add(event) {
handleRequest(math,new Array(+));
}
La commande math est passe en premier paramtre et un tableau contenant uniquement
le caractre + est pass en second paramtre. Dans ce cas, lutilisation dun tableau en
second paramtre peut sembler inutile, mais la conception impose ce paramtre et cette
solution est beaucoup plus exible, comme vous le verrez plus loin.
Tableau 2.1 : LAPI du contrleur frontal
Mthode Valeur de retour Paramtres
handleRequest(aCmd, paramArray) void aCmd une chane unique qui repr-
sente le comportement traiter, par
exemple "displayBlogEntries".
paramArray un paramtre facultatif
constitu dun tableau de variables qui
peuvent tre requises pour le traitement.
iPhone Livre Page 37 Vendredi, 30. octobre 2009 12:04 12
38 Dveloppez des applications pour liPhone
La fonction add correspond au gestionnaire onclick dun bouton. Lors dun clic sur le
bouton correspondant, toutes les ValCF, BCF et VCF associes la commande math sont
excutes, avec le tableau de paramtres en argument. Vous remarquerez que les gestion-
naires subtract, multiply et divide emploient la mme commande que la fonction add,
mais passent un caractre diffrent dans le tableau.
Dans notre exemple, lapplication rutilise le mme code de ValCF, BCF et VCF pour
chaque fonctionnalit. Il serait possible dutiliser une commande diffrente dans chaque
gestionnaire avec diffrentes BCF et de rutiliser ensuite les mmes ValCF et VCF, mais
les diffrentes BCF requises pour chaque type doprations arithmtiques seraient trs
semblables. Nous avons donc choisi de crer une seule BCF.
La Figure 2.3 illustre le ux de commande dans lapplication simpleCalc, aprs que
lutilisateur a cliqu sur lun des boutons dopration arithmtique. Dans cet exemple,
deux ValCF sont excutes pour dterminer si le traitement peut se poursuivre.
Noubliez pas que la conception modulaire montre ici fait respecter lordre des appels
de fonctions.
Figure 2.2
Lapplication simpleCalc
aprs un appui sur le
bouton daddition.
iPhone Livre Page 38 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 39
La premire ValCF vrie que les deux valeurs saisies par lutilisateur sont des nombres. La
seconde, divisionByZeroValCF, vrie quune division par zro ne peut pas se produire.
Aprs la validation, la fonction calculateSolutionsBCF est invoque. Cette BCF effec-
tue lopration arithmtique demande par lutilisateur. La fonction displaySolutionVCF
afche ensuite le rsultat (voir Figure 2.2).
En revanche, si la requte ne franchit pas lune des ValCF, la conception modulaire prsente
dispose de fonctions de contrle pour grer cette situation.
Les fonctions de contrle des erreurs (ECF, Error Control Function) sont des fonctions de
contrle utilises pour traiter les cas derreur. Si lune des ValCF choue, la fonction
entryECF est appele (voir Figure 2.4). Elle signale lutilisateur une erreur dans les
valeurs quil a saisies.
Comment la commande math est-elle associe aux quatre fonctions de contrle qui
doivent tre excutes ? QuickConnectiPhone fournit pour cela quatre fonctions utilitaires
(voir Tableau 2.2). Chacune delles associe une commande une fonction de contrle.
Figure 2.3
Ordre dexcution des
fonctions de contrle
associes la commande
math.
Figure 2.4
La conception du ux
de la commande math.
checkNumbersValCF
divisionByZeroValCF
calculateSolutionBCF
displaySolutionVCF
Flux dune commande
checkNumbersValCF
entryECF
divisionByZeroValCF
calculateSolutionBCF
displaySolutionVCF
math
badNum
divZero
iPhone Livre Page 39 Vendredi, 30. octobre 2009 12:04 12
40 Dveloppez des applications pour liPhone
Le code suivant, qui correspond aux lignes 24 27 du chier mappings.js, montre lasso-
ciation de la commande math aux fonctions de contrle, ainsi que celle des erreurs badNum
et divZero.
// Associer une commande plusieurs fonctions.
mapCommandToValCF(math,checkNumbersValCF);
mapCommandToValCF(math,divisionByZeroValCF);
mapCommandToBCF(math, calculateSolutionBCF);
mapCommandToVCF(math, displaySolutionVCF);
// Associer plusieurs commandes une fonction.
mapCommandToECF(badNum, entryECF);
mapCommandToECF(divZero, entryECF);
Tableau 2.2 : LAPI des fonctions dassociation
Mthode Valeur de retour Paramtres
MapCommandToValCF(command,
validationControlFunction)
void command une chane unique qui reprsente le
comportement traiter, par exemple math.
validationControlFunction une fonction de
validation excuter lorsque la commande est
reue par handleRequest.
MapCommandToBCF(command,
businessControlFunction)
void command une chane unique qui reprsente le
comportement traiter, par exemple math.
businessControlFunction une fonction
mtier excuter lorsque la commande est reue
par handleRequest.
MapCommandToVCF(command,
viewControlFunction)
void command une chane unique qui reprsente le
comportement traiter, par exemple math.
viewControlFunction une fonction daf-
chage excuter lorsque la commande est reue
par handleRequest.
MapCommandToECF(command,
errorControlFunction)
void command une chane unique qui reprsente le
comportement traiter, par exemple divZero.
errorControlFunction une fonction
derreur excuter lorsque la commande est reue
par handleRequest.
iPhone Livre Page 40 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 41
Un contrleur frontal bien conu ne doit tre crit quune seule fois et doit pouvoir tre
rutilis dans plusieurs applications. La conception particulire du contrleur frontal et du
contrleur dapplication prsente dans ce chapitre offre galement une solution simple
pour concevoir les comportements spciques de vos applications.
Puisque cette conception garantit que les fonctions de contrle de la validation sont excutes
en premier et sont suivies de toutes les BCF et VCF, lorganisation de la conception au
niveau des fonctions de lapplication devient plus facile (voir Figure 2.4).
Cette conception gnrale du framework garantit galement que les fonctions de contrle
sont excutes dans lordre dans lequel elles sont associes aux commandes. Dans le code
prcdent, la fonction checkNumbersValCF est toujours invoque avant divisionByZero-
ValCF.
Contrleurs dapplication
Un contrleur dapplication, fond sur le pattern de contrleur dapplication standard,
est utilis pour associer des commandes des fonctionnalits prcises. Ainsi, les impl-
mentations du pattern impliquent gnralement une mappe dont les cls correspondent
aux commandes et les valeurs, aux fonctionnalits cibles.
Avec la conception dcrite dans ce chapitre, les valeurs associes aux cls de la mappe sont
des listes de fonctions. Cela permet au contrleur dexcuter plusieurs fonctions dans
lordre indiqu et daugmenter la modularit et la rutilisabilit des cibles de la fonction
de contrle.
Un contrleur dapplication bien conu permet dobtenir une application volutive, car
une fonctionnalit peut tre ajoute sans rcrire le fonctionnement interne de lapplication.
La mise en uvre du contrleur dapplication de QuickConnectiPhone en est un exemple.
Puisque vous savez prsent comment les commandes sont associes aux fonctions de
contrle, il est temps dexaminer la cration de ces dernires. La fonction checkNumbers-
ValCF est un exemple relativement classique de ValCF. Elle se focalise sur une tche,
cest--dire vrier uniquement que les valeurs saisies par lutilisateur sont des nombres.
Si la validation choue, elle invoque un contrleur dapplication, dispatchToECF, pour
traiter lerreur :
function checkNumbersValCF(parameters) {
// Vrifier que a et b sont des nombres.
var a = document.getElementById(a).value;
iPhone Livre Page 41 Vendredi, 30. octobre 2009 12:04 12
42 Dveloppez des applications pour liPhone
var b = document.getElementById(b).value;
if(isNaN(a) || isNaN(b)) {
dispatchToECF(badNum,Saisissez uniquement des nombres.);
return false;
}
return true;
}
Les ValCF retournent true si la validation est positive, sinon false. Cela permet darrter
immdiatement le traitement en cas dchec et, par voie de consquence, daugmenter la
scurit de lapplication.
Prcdemment, la fonction calculateSolutionBCF a t associe en tant que BCF la
commande math. Comme la plupart des BCF, elle obtient des donnes sur lesquelles
elle opre. Dans ce cas, elle prend ses donnes dans linterface utilisateur. Dans
dautres cas, une BCF peut prendre des valeurs dans une base de donnes ou, en utili-
sant AJAX, partir dun serveur sur Internet. Le code suivant montre limplmentation
de cette BCF :
function calculateSolutionBCF(parameters){
var a = document.getElementById(a).value;
var b = document.getElementById(b).value;
if(a == ){
a = 0;
}
if(b == ){
b = 0;
}
// valuer le rsultat de lopration.
var expression = a+parameters[0]+b;
var result = eval(expression);
return new Array(a, b, result);
}
la place de la valeur boolenne des ValCF, les BCF retournent un tableau dinforma-
tions. Il contient toute information que vous choisissez dinclure. Dans notre cas, les
deux valeurs saisies par lutilisateur et le rsultat calcul sont retournes, car ces
donnes seront ncessaires pour gnrer les informations afches lutilisateur (voir
Figure 2.2).
Le calcul rel du rsultat se fait avec la fonction JavaScript eval. Cette fonction tente
dexcuter une chane qui contient un code JavaScript valide. Dans cet exemple, si
iPhone Livre Page 42 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 43
lutilisateur saisit les valeurs 3 et 5 et clique sur le bouton daddition, la variable expres-
sion contient la chane "3+5". Lorsque cette chane est passe eval, cette fonction
retourne 8.
Faites attention lorsque vous utilisez la fonction eval, car elle excute la chane, quelle
quelle soit. Dans lapplication simpleCalc, cela ne pose pas de problme, car la ValCF
vrie que les valeurs a et b sont bien des nombres. Si les lments utiliss dans un appel
eval ntaient pas valids, des utilisateurs pourraient dcouvrir le fonctionnement
interne des applications et avoir des agissements nfastes, comme une attaque par insertion
SQL si la BCF accde une base de donnes.
displaySolutionVCF est un exemple simple de VCF. Comme les autres fonctions de
contrle, elle ralise une seule chose : actualiser le <div> qui contient la chane reprsentant
lopration arithmtique effectue et le rsultat calcul.
function displaySolutionVCF(data, parameters){
var result = data[0][0]+ +parameters[0] +
+data[0][1]+ = +data[0][2];
document.getElementById(display).innerHTML = result;
}
En gnral, les VCF actualisent le contenu HTML de la page principale. Par exemple, une
modication majeure de la vue consiste changer lintgralit de linterface graphique.
Notre exemple effectue une petite modication en afchant le calcul arithmtique effectu
et en ne touchant pas au reste de linterface graphique.
Les ECF peuvent tre simples ou complexes. Elles peuvent modier des donnes enregis-
tres ou tre aussi simples que la fonction entryECF suivante, qui reoit une chane de
caractres en paramtre et lafche lutilisateur.
function entryECF(message){
document.getElementById(display).innerHTML = message;
}
En raison de sa simplicit, cette ECF peut tre utilise par les deux ValCF de notre application
en cas dchec de la validation.
Avec une bonne implmentation de la conception contrleur frontal-contrleur dapplica-
tion, vous pouvez focaliser la conception et limplmentation de lapplication sur le
comportement souhait, non sur les communications et les passages de donnes entre les
fonctions. La section suivante dcrit la mise en uvre dun contrleur frontal et de contrleurs
dapplication.
iPhone Livre Page 43 Vendredi, 30. octobre 2009 12:04 12
44 Dveloppez des applications pour liPhone
Section 3 : conception modulaire
dans QuickConnectiPhone
Comme la plupart des autres parties de limplmentation de la conception dcrite dans ce
chapitre, la fonction handleRequest est courte. Elle et la mthode pour laquelle elle sert
de faade occupent vingt-trois lignes. Les lignes qui nous intressent sont prsentes en
gras (7 21).
Puisque handleRequest implmente le contrleur frontal de la conception examine la
section prcdente, elle est responsable de lappel des quatre contrleurs dapplication.
Chaque contrleur dapplication prend en charge un type de fonction de contrle. Comme le
montre la ligne 7, dispatchToValCF est le premier contrleur dapplication invoqu.
Le Tableau 2.3 dcrit chaque fonction contrleur dapplication.
Tableau 2.3 : LAPI du contrleur dapplication
Mthode Valeur de retour Paramtres
dispatchToValCF
(aCmd, paramArray)
Boolen (true en cas de suc-
cs, false en cas dchec).
aCmd une chane unique qui
reprsente le comportement trai-
ter, par exemple displayBlog-
Entries.
paramArray un paramtre faculta-
tif constitu dun tableau de variables
requises pour le traitement.
dispatchToBCF(aCmd,
paramArray, callBackData)
Les donnes prtes tre af-
ches ou stop. Si stop est
retourn, le traitement de la
commande indique sarrte.
aCmd une chane unique qui repr-
sente le comportement traiter, par
exemple displayBlogEntries.
paramArray un paramtre faculta-
tif constitu dun tableau de variables
requises pour le traitement.
callBackData un paramtre
facultatif gnr par le framework si
des appels asynchrones sont effectus
depuis une BCF associe la com-
mande.
iPhone Livre Page 44 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 45
dispatchToValCF appelle toutes les ValCF qui ont t associes la commande indique
par la variable aCmd. Si les fonctions de validation russissent, dispatchToValCF retourne
la valeur boolenne true ; dans le cas o lune des ValCF choue, elle retourne false.
Puisque lappel dispatchToValCF est plac dans une instruction if, la poursuite du trai-
tement de la requte est conditionne par le retour de la valeur true. Si ce nest pas le cas,
la requte entre dans la routine de traitement des erreurs, mais seulement si des ECF ont
t associes la commande principale. Dans lapplication simpleCalc, une telle associa-
tion nexiste pas.
1 function handleRequest(aCmd, paramArray){
2 requestHandler(aCmd, paramArray, null);
3 }
4
5 function requestHandler(aCmd, paramArray, callBackData){
6 if(aCmd!= null){
7 if(dispatchToValCF(aCmd, paramArray)){
8 try{
9 var data = dispatchToBCF(aCmd,
dispatchToVCF(aCmd, data,
paramArray)
void aCmd une chane unique qui repr-
sente le comportement traiter, par
exemple displayBlogEntries.
data un tableau constitu de toutes
les donnes gnres par les appels
aux BCF.
paramArray un paramtre faculta-
tif constitu dun tableau de variables
requises pour le traitement.
dispatchToECF(aCmd,
errorMessage)
void aCmd une chane unique qui repr-
sente le comportement traiter, par
exemple databaseDown.
errorMessage un message daver-
tissement, journalis pour le dve-
loppeur ou afch lutilisateur, qui
doit tre sufsamment descriptif et
utile pour le type dutilisateur auquel
il est destin.
Tableau 2.3 : LAPI du contrleur dapplication (suite)
Mthode Valeur de retour Paramtres
iPhone Livre Page 45 Vendredi, 30. octobre 2009 12:04 12
46 Dveloppez des applications pour liPhone
10 paramArray, callBackData);
11 if(data!= stop){
12 dispatchToVCF(aCmd, data, paramArray);
13 }
14 }
15 catch(err){
16 logError(err);
17 }
18 }
19 else{
20 dispatchToECF(aCmd, chec de la validation);
21 }
22 }
23 }
Aprs que la requte a pass la validation, le module du contrleur frontal appelle le
contrleur dapplication suivant, dispatchToBCF. Cette fonction contrleur invoque les
BCF associes la commande de manire obtenir ou enregistrer des donnes.
Si une BCF retourne des donnes autres que stop, le contrleur frontal appelle les VCF
associes la commande. Pour cela, il invoque le troisime contrleur dapplication,
dispatchToVCF. Pour de plus amples informations concernant les BCF et les VCF, consultez
la Section 4.
Lobjectif du module du contrleur frontal mentionn prcdemment est doffrir une solu-
tion rapide et simple pour garantir un ux de calcul stable et scuris dans lapplication.
Lorsquun ux est employ de manire cohrente, il est beaucoup plus facile de crer et de
dboguer les applications. Par consquent, lorsque vous utilisez la version QuickConnecti-
Phone de la conception, il est ncessaire dinvoquer la fonction handleRequest si vous
voulez que lapplication fasse quelque chose.
Chaque fonction de contrle de lapplication dcrite au Tableau 2.3 joue un rle distinct et
permet la poursuite ou larrt du traitement de la commande en fonction des dcisions que
vous prenez dans vos ValCF et vos BCF. Elles correspondent la notion de module car
elles sont rutilisables, faiblement couples et fortement cohsives.
La fonction dispatchToValCF est une faade. Du point de vue comportement, elle est
identique la fonction dispatchToSCF, mais elles manipulent toutes deux des jeux de
donnes diffrents. Les ValCF servent valider la saisie de lutilisateur. Les fonctions de
contrle de la scurit (SCF, Security Control Function) permettent de garantir que les
donnes obtenues partir de sources distantes, comme des sites web, ne contiennent pas
du code malveillant. En raison de leur objectif semblable, il est prfrable de centraliser le
code rel et dutiliser des fonctions de faade pour invoquer la fonction check sous-
jacente.
iPhone Livre Page 46 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 47
Le code suivant, tir du chier QuickConnect.js, prsente la fonction de faade dispatch-
ToValCF et la fonction check sous-jacente. Vous le constatez, la fonction dispatchTo-
ValCF invoque check en lui passant ses deux paramtres, plus un autre. Ce paramtre
supplmentaire est une chane qui dcrit le type de mappe que la fonction check va utiliser.
Cette mappe, ou tableau associatif, contient toutes les associations entre les commandes et
un tableau de ValCF. Pour crer et associer des commandes des ValCF, consultez la
Section 2 de ce chapitre.
1 function dispatchToValCF(validationCommand, paramArray){
2 return check(validationCommand, validation, paramArray);
3 }
4
5 /*
6 * Cette fonction ne doit pas tre appele directement par le programmeur.
7 */
8 function check(command, type, data){
9 var retVal = true;
10 /*
11 * Excuter toutes les fonctions par dfaut dfinies qui sappliquent toutes
les commandes.
12 */
13 var map = securityMap;
14 if(type == validation){
15 map = validationMap;
16 }
17 var defaultFuncs = map[default];
18 if(defaultFuncs){
19 var numFuncs = defaultFuncs.length;
20 for(var i = 0; i < numFuncs; i++){
21 retVal = defaultFuncs[i](command, data);
22 if(retVal == false){
23 break;
24 }
25 }
26 }
27 /*
28 * Si les fonctions par dfaut ont russi, excuter celles spcifiques la
commande.
29 */
30 if(retVal == true){
31 commandFuncs = map[command];
32
iPhone Livre Page 47 Vendredi, 30. octobre 2009 12:04 12
48 Dveloppez des applications pour liPhone
33 if(commandFuncs){
34 var numFuncs = commandFuncs.length;
35 for(var i = 0; i < numFuncs; i++){
36 retVal = commandFuncs[i](data);
37 if(retVal == false){
38 break;
39 }
40 }
41 }
42 }
43 return retVal;
44 }
la ligne 17, le code tente dobtenir un tableau des fonctions de contrle associes la
commande default. Autrement dit, vous pouvez crer une VCF qui, en lassociant
default, sera appele pour chaque commande envoye handleRequest.
Une ValCF par dfaut classique sassure quune association pour la commande passe
existe, que ce soit dans la mappe des BCF, des VCF ou les deux. Si la commande
nexiste pas dans ces fonctions, il ny a aucune raison de poursuivre le traitement de la
commande. Par consquent, elle stoppe alors les contrles de validit suivants et
retourne false.
En retournant false, elle conduit galement la fonction dispatchToValCF retourner
false immdiatement, ce qui conduit le contrleur frontal arrter le traitement. Cette
ValCF dtecte les commandes errones sans association avant quelles ne soient sources
de problmes ultrieurs dans lapplication.
Sil nexiste aucune ValCF par dfaut ou si la commande a pass toutes celles associes
default, la fonction check se poursuit en obtenant la liste des ValCF associes la
commande spcique fournie en argument et les excute dans lordre.
Comme expliqu la Section 2, ce contrle pralable des saisies de tout type fait partie
des objectifs de la fonction dispatchToValCF et des ValCF que vous crez. Il permet
galement de sparer le code de validation et le code dexcution. Grce cette sparation,
ces deux parties du code sont parfaitement identies et la maintenance de lapplication
est simplie. Il facilite galement la cration du logiciel en simpliant le processus de
conception (voir Section 2).
iPhone Livre Page 48 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 49
Section 4 : implmentation des contrleurs mtier
et dafchage
De ces deux contrleurs dapplication, le plus complexe est le contrleur mtier, tandis
que le plus simple est le contrleur dafchage simple. La fonction dispatchToBCF
appelle toutes les BCF associes une commande, mme si une ou plusieurs des BCF
effectuent des appels asynchrones. La fonction dispatchToVCF est plus simple car elle
ressemble fortement la fonction dispatchToValCF et les VCF ne sont jamais asynchrones.
Bien que le comportement de ces fonctions soit comparable, leur implmentation est tota-
lement diffrente.
Nous lavons expliqu la Section 2, la fonction de contrle mtier dispatchToBCF est
invoque uniquement si les ValCF que vous avez dnies et associes indiquent que le
traitement peut se poursuivre. Bien que cette fonction se fonde sur des ides quivalentes,
elle est bien diffrente de la mthode checkValidation.
La fonction dispatchToBCF est constitue de deux parties principales. La premire
correspond aux lignes 18 40 et concerne le tableau callBackData. Ce tableau reprsente
les donnes accumules au cours dun appel asynchrone. Si la BCF neffectue aucun appel
asynchrone, ce tableau est vide. Dans le cas contraire, par exemple avec un appel AJAX ou
un appel pour consulter une base de donnes, ce tableau contient les donnes ncessaires
lappel des autres BCF associes la commande. Les lignes 25 et 31 montrent que ce
tableau callBackData contient les rsultats retourns par toutes les BCF invoques avant
lappel asynchrone et les donnes gnres par celui-ci.
Dnition dasynchrone
En informatique, nous avons coutume de raisonner de manire synchrone. Autrement dit,
les choses se font une la fois, dans un ordre dni. Lors de lappel une fonction, on
sattend ce que chaque tape de la fonction soit excute dans lordre. Lorsque toutes
les tapes sont termines, la fonction retourne ou non une valeur.
Un comportement asynchrone est bien diffrent. Il ressemble plus une partie de foot-
ball. Dans ce jeu, chaque joueur soccupe de la fonction attribue son poste, quelle que
soit lactivit des autres joueurs. Tout autre comportement serait stupide. Imaginez un
match dans lequel tous les joueurs attendraient que les autres joueurs aient ni leur
action avant de commencer bouger...
En informatique, un comportement asynchrone signie quune fonction peut jouer son
rle, mais que le traitement continue sans attendre le retour de la fonction.
iPhone Livre Page 49 Vendredi, 30. octobre 2009 12:04 12
50 Dveloppez des applications pour liPhone
La ligne 34 ajoute au tableau results les donnes gnres par lappel asynchrone, dans
le cas o aucun appel de BCF prcdent na t effectu. Ainsi, aprs lexcution de
cette ligne, le reste du code voit le tableau results comme si aucun appel asynchrone
navait eu lieu.
La ligne 37 obtient lindice de la BCF qui a effectu lappel asynchrone. Ainsi, le reste du
code de la fonction dispatchToBCF sait combien de BCF associes la commande ont
dj t excutes. Les appels asynchrones constituent une "rupture" dans lexcution des
BCF associes la commande. La fonction dispatchToBCF ne sait pas quelles BCF ont
dj t excutes, jusqu ce quun indicateur soit inclus dans les donnes gnres par
lappel asynchrone.
Au Chapitre 7, cela est mis en place par les mthodes getData, setData, getNativeData
et setNativeData de la classe DataAccessObject. Si vous crez votre propre framework
qui autorise les appels asynchrones, vous devez crer un code semblable au suivant :
1 function dispatchToBCF(aCmd, paramArray, callBackData){
2
3 if(event == null){
4 event = window.event;
5 }
6 if(event!= null){
7 stopDefault(event);
8 }
9 window.curCmd = aCmd;
10 if(paramArray){
11 window.globalParamArray = paramArray;
12 }
13 else{
14 window.globalParamArray = new Array();
15 }
16 var results = new Array();
17 window.numFuncsCalled = 0;
18 if(callBackData){
19 if(callBackData[0]){
20 if(callBackData[1]){
21 var accumulatedDataFromCallback =
22 callBackData[1][3];
23 if(accumulatedDataFromCallback &&
24 accumulatedDataFromCallback.length > 0){
25 results = accumulatedDataFromCallback;
26 }
27 }
iPhone Livre Page 50 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 51
28 if(results.length == 0){
29 // results doit toujours tre un tableau.
30 // Les crochets ([]) sen assurent.
31 results = [callBackData[0]];
32 }
33 else{
34 results.push(callBackData[0]);
35 }
36 }
37 if(callBackData[1]){
38 window.numFuncsCalled = callBackData[1][1];
39 }
40 }
41 var stop = false;
42 if(aCmd){
43 var commandList = businessMap[aCmd];
44 callFunc = function(data){
45 if(data){
46 results.append(data);
47 window.globalBCFResults = results;
48 }
49 if(window.numFuncsCalled < commandList.length){
50 var funcToCall =
51 commandList[window.numFuncsCalled];
52 window.numFuncsCalled++;
53 var result = null;
54 try{
55 result = funcToCall(paramArray,
56 results);
57 }
58 catch(err){
59 dispatchToECF(runFailure,
60 err.message);
61 }
62
63 if(result!= null){
64 results[results.length] = result;
65 callFunc();
66 }
67 else{
68 stop = true;
69 }
70 }
71 }
iPhone Livre Page 51 Vendredi, 30. octobre 2009 12:04 12
52 Dveloppez des applications pour liPhone
72 if(commandList && commandList.length > 0){
73 callFunc();
74 }
75 }
76 if(stop){
77 return stop;
78 }
79 return results;
80 }
Les lignes 41 80 de la fonction de contrle dispatchToBCF illustrent la manire de rali-
ser trois choses :
crer et utiliser des fonctions JavaScript anonymes ;
employer la rcursivit en JavaScript ;
appeler les BCF associes une commande.
Une fonction anonyme est une fonction qui est cre " la vole" lintrieur dune autre
fonction. Dans le code prcdent, la fonction callFunc, aux lignes 44 71, en est un
exemple. Cette fonction nexiste pas en dehors de dispatchToBCF. Comme nimporte
quelle fonction anonyme, elle est strictement limite la porte de la fonction dans
laquelle elle est dclare. Par ailleurs, les variables dclares dans la fonction conteneur
avant la dclaration de la fonction anonyme sont dans la porte et peuvent tre utilises
dans la fonction anonyme, mme si elles ne sont pas passes en paramtres.
Les lignes 43 et 44 en sont un exemple. La variable commandList est dnie en dehors de
la fonction callFunc, elle ne lui est pas passe en paramtre, mais elle est employe dans
cette fonction. Elle est utilise aux lignes 50 et 51 pour obtenir la prochaine BCF excuter.
Les lignes 55 et 56 excutent cette BCF et enregistrent les rsultats de linvocation.
Un exemple de rcursivit se trouve la ligne 65, o la fonction callFunc sappelle elle-
mme. Cela se produit la n de la fonction, uniquement si le rsultat de lappel la BCF
nest pas null. Ce type de rcursivit est appel rcursivit nale car la vrication se
trouve la n de la fonction. Si elle se trouvait au dbut de la fonction, il sagirait dune
rcursivit initiale. La cascade dappels rcursifs est dclenche par lappel callFunc
la ligne 73.
Rcursivit
La rcursivit correspond lappel dune fonction par elle-mme.
iPhone Livre Page 52 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 53
Lorsque la fonction dispatchToVCF est invoque, une liste des fonctions de contrle asso-
cies la commande est obtenue (voir le code ci-aprs). Contrairement la fonction de
contrle de la validation, dispatchToVCF reoit en argument un tableau contenant les
lments qui correspondent aux rsultats des appels chacune des BCF.
linstar de la fonction dispatchToBCF, si lune des VCF retourne stop, aucune autre
nest excute. Cela permet aux programmeurs de terminer lexcution en faisant un appel
dispatchToECF.
function dispatchToVCF(aCmd, data, paramArray){
if(aCmd){
var vcfFuncList = viewMap[aCmd];
if(vcfFuncList == null){
vcfFuncList = new Array();
}
var numFuncs = vcfFuncList.length;
for(var i = 0; i < numFuncs; i++){
try{
retVal = vcfFuncList[i](data, paramArray);
}
catch(err){
debug(errorMessage(err));
}
if(retVal && retVal == stop){
break;
}
}
}
}
Aprs quune VCF a t obtenue, elle est invoque avec les donnes rsultantes de la BCF
et les paramtres dorigine, paramArray, envoys par lapplication la fonction handle-
Request. Cela permet de passer des informations aux BCF et aux VCF invoques par les
contrleurs dapplication mtier et dafchage.
Section 5 : implmentation dun contrleur derreur
Contrairement aux autres contrleurs dapplication examins aux Sections 3 et 4, la mise
en uvre du contrleur derreur dans le framework QuickConnectiPhone nautorise
lassociation que dune seule ECF une commande. Autrement dit, chaque ECF doit grer
intgralement lerreur, ce qui inclut modier des donnes enregistres, actualiser la vue
pour avertir les utilisateurs, etc.
iPhone Livre Page 53 Vendredi, 30. octobre 2009 12:04 12
54 Dveloppez des applications pour liPhone
Voici un exemple dimplmentation simple dun contrleur derreur :
function dispatchToECF(errorCommand, errorMessage){
var errorFunc = errorMap[errorCommand];
if(errorFunc){
return errorFunc(errorMessage);
}
}
Cette version obtient simplement lECF excuter et lui passe le message derreur. Pour
activer une telle gestion des erreurs, il faut effectuer un appel direct dispatchToECF,
sans passer par un appel handleRequest. La ligne de code suivante est extraite de la
fonction checkNumbersValCF :
dispatchToECF(badNum, Saisissez uniquement des nombres.);
Cet appel dispatchToECF contient le message qui doit tre afch an dinformer
lutilisateur que seuls les nombres sont accepts.
Section 6 : tapes de cration dune fonctionnalit
de lapplication
Les Sections 3 5 ont expliqu ce qui se passe en coulisse lorsque vous utilisez limpl-
mentation des contrleurs frontaux et dapplication propose par le framework Quick-
ConnectiPhone. Mais quelles sont les tapes suivre pour mettre en uvre une fonctionnalit
de lapplication ? Les voici, dans lordre :
1. Crer les BCF pour obtenir ou enregistrer les donnes (voir Section 4).
2. Crer les VCF pour modier linterface utilisateur (voir Section 4).
3. Crer les ValCF ncessaires la validation de la saisie de lutilisateur (voir Section 3).
4. Crer les ECF ncessaires la gestion des conditions derreur possibles (voir Section 5).
5. Associer toutes les fonctions de contrle une commande en utilisant les fonctions
mapCommandTo* correspondantes.
Aprs avoir termin ces cinq tapes, la nouvelle fonctionnalit est intgre lapplication.
iPhone Livre Page 54 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 2 Modularit JavaScript 55
En rsum
Lorsquelle est applique correctement, la modularit facilite lcriture de code, simplie
sa maintenance et rduit sa taille. En gardant cela lesprit, ainsi que la rapidit dexcution,
limplmentation apporte par le framework QuickConnectiPhone chaque application
cre laide de ses modles facilite normment votre travail. Vous pouvez vous concen-
trer sur votre objectif, cest--dire crer et fournir une fonctionnalit vos utilisateurs.
Le framework soccupe de toutes les communications et des contrles internes.
En crivant des ValCF, des BCF, des VCF et des ECF, vous pouvez aisment focaliser
votre travail de manire augmenter la productivit. Dans le mme temps, vous augmentez
galement la qualit et la scurit de votre code.
iPhone Livre Page 55 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 56 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
3
Interfaces utilisateur
LiPhone permet de proposer des mthodes dinteraction uniques avec lutilisateur. Sur ce
tlphone, les anciennes mthodes de conception des interfaces ne sufsent plus. Votre
application doit offrir les interactions et les lments dinterfaces que les utilisateurs de
liPhone rclament. Ce chapitre explique comment procder. Il sintresse galement au
guide dinterface utilisateur employ par Apple pour dcider de lajout des applications
dans lApp Store. Un module de redimensionnement, de rotation et de glisser-dposer
est galement dcrit an que vous appreniez traiter les vnements lis au toucher et
aux gestes en JavaScript. Ces nouveaux types dvnements JavaScript sont essentiels
la conception des interfaces utilisateur pour liPhone.
Section 1 : guide de linterface utilisateur dApple
Pour que tous les utilisateurs de liPhone partagent la mme exprience, Apple a rdig un
guide qui stipule les rgles suivre lors de la conception des interfaces utilisateur des
applications pour liPhone. Cette section introduit le HIG (Human Interface Guide) pour
liPhone de manire concise et simple. Sa version intgrale peut tre consulte ladresse
http://developer.apple.com/iphone/library/documentation/UserExperience/Conceptual/
MobileHIG/Introduction/Introduction.html.
iPhone Livre Page 57 Vendredi, 30. octobre 2009 12:04 12
58 Dveloppez des applications pour liPhone
Le HIG pour liPhone trouve ses origines dans les guides crs prcdemment pour OS X
et le dveloppement web pour liPhone. Ce nouveau guide se fonde sur les points forts des
prcdents et ajoute de nouveaux aspects spciques aux applications pour liPhone.
La place disponible sur lcran de liPhone est tellement limite que lafchage dun texte
lutilisateur peut vite devenir pnible. Pour les applications dont la fonction principale
nest pas de prsenter des donnes textuelles, il est prfrable demployer des images et
des icnes pour communiquer des ides et offrir des fonctionnalits utilisateur.
Labandon des informations textuelles se trouve au cur de liPhone. Cet appareil ne
prsente pas de menus droulants ou de rubans, et vos applications ne doivent pas en utiliser.
Si lapplication est bien conue, son utilisation doit se rvler intuitive. Si elle nest pas
intuitive, lapplication nest pas conue pour liPhone. Si elle est bien conue, elle na
besoin daucun guide de lutilisateur.
Les menus droulants ont prolifr car les applications nont plus un seul usage mais
plusieurs. Si vous examinez les applications bureautiques existantes, il est facile de voir
comment elles sont parties dapplications initialement simples, lusage bien dni, pour
devenir des monstres de fonctionnalits.
Les logiciels de traitement de textes ne sont plus vraiment des traitements de textes. Ils
permettent de crer des mises en page sophistiques, sont capables dinclure des donnes
provenant dapplications totalement diffrentes et offrent mme un environnement de
dveloppement. Si cette enchre de fonctionnalits a permis de conserver la viabilit des
applications, celles-ci sont devenues volumineuses et lourdes.
Chaque application pour liPhone doit avoir un et un seul objectif ou fonction. Il doit tre
facile identier et facile matriser par lutilisateur. En respectant les standards dApple,
vos applications seront plus facilement comprhensibles et apporteront lutilisateur une
exprience plus plaisante.
Le contrle de lapplication est un lment vital dans toute conception. Lutilisateur doit
disposer du plus grand contrle possible. Autrement dit, lapplication ne doit pas le
contraindre des comportements prcis. La limitation des options est vue dun mauvais
il dans les applications pour liPhone. Pour arriver ce rsultat, les vues dune applica-
tion doivent tre organises plat. Les profondes hirarchies de vues augmentent la charge
de travail de lappareil et sont dconseilles.
Puisque les interactions avec liPhone se font par des gestes, comme le toucher et le
toucher multiple, lapplication doit galement les prendre en charge. Chaque zone de
toucher doit tre dimensionne de manire approprie pour que lutilisateur puisse la
slectionner. Normalement, la largeur et la hauteur dune zone de toucher doivent tre
gales 34 pixels. Si elles sont plus petites, par exemple pour gagner de la place sur
iPhone Livre Page 58 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 59
lcran, lutilisateur risque davoir des difcults slectionner les lments et nen sera
que plus mcontent.
Mme si le balayement (swipe) et le pincement (pinch) sont des comportements pris en
charge, les utilisateurs peuvent avoir du mal savoir quils existent. Si vous souhaitez les
inclure, ajoutez des indicateurs visuels qui informent de leur disponibilit. Par exemple,
dans une application de type livre lectronique, ces indicateurs peuvent prendre la forme
de coins de page plis.
Le glisser-dposer est gnralement dconseill par le HIG, car la mme interaction de
lutilisateur sert habituellement au dlement ou au dplacement panoramique. Toutefois,
il est facile de trouver des applications russies qui utilisent cette fonctionnalit. Apple a
mme crit en JavaScript un exemple excessivement complexe de ce comportement.
La seconde partie de ce chapitre explique comment mettre en uvre le glisser-dposer, le
pincement pour le redimensionnement et la rotation des lments de linterface.
Le Tableau 3.1 rcapitule les diffrents types de gestes reconnus et les comportements standard
associs. En respectant ces fonctionnements, la phase dapprentissage de lapplication est
rduite. En revanche, si vous rednissez les comportements associs, elle devient plus longue.
LiPhone est un appareil rellement extraordinaire, mais la saisie dun texte peut tre pni-
ble et lente compare lutilisation dun clavier standard. Autant que possible, essayez
dutiliser des slecteurs de donnes la place dune saisie directe. Dans les applications
Tableau 3.1 : Gestes reconnus par liPhone et comportements standard associs
Geste Comportement
Toucher (tap) Slection dun lment de linterface utilisateur.
Glissement (drag) Dlement ou dplacement panoramique pour un autre af-
chage.
Dlement (ick) Dlement ou dplacement panoramique rapide. Une fois le
geste termin, le comportement doit se poursuivre.
Balayement (swipe) Rvlation des composants cachs, comme des boutons de sup-
pression dune ligne dune table ou des vues supplmentaires.
Double-toucher (double tap) Centrage, puis zoom avant ou arrire.
Pincement vers lextrieur (pinch open) Zoom avant.
Pincement vers lintrieur (pinch close) Zoom arrire.
Toucher et maintien Afchage dune vue agrandie.
iPhone Livre Page 59 Vendredi, 30. octobre 2009 12:04 12
60 Dveloppez des applications pour liPhone
hybrides, les slecteurs apparaissent lorsque lutilisateur active une balise HTML
<option>. Grce aux slecteurs, les utilisateurs matrisent plus rapidement votre applica-
tion et leur niveau de frustration diminue. Le Chapitre 4 explique comment inclure des
slecteurs de date et dheure dans les applications hybrides.
Le document de standardisation des applications pour liPhone stipule que les cases
cocher et les boutons radio doivent tre vits. la place, il est prfrable dutiliser des
interrupteurs. Lapplication Rglages fournie avec chaque iPhone et iPod Touch les utilise
normment. La Figure 3.1 illustre les options de Safari que vous pouvez modier dans
lapplication Rglages. Les dveloppeurs dapplications hybrides ont quelques difcults
viter les boutons radio et les cases cocher.
Loutil Dashcode utilis pour dvelopper linterface graphique des applications hybrides ne
dispose pas dune widget de type interrupteur, mais il est facile de la crer. Elle est constitue
dune bote avec une bordure interne, deux lments de texte, 1 et 0, et un bouton.
En utilisant les vnements de geste sur le bouton, il est facile de le faire glisser droite ou
gauche de manire rvler ltat de linterrupteur. La fonction de rappel ongestureend
dnie pour le bouton permet de dtecter et denregistrer son tat allum (1) ou teint (0).
Servez-vous des boutons de rglage de Safari illustrs la Figure 3.1 pour crer les vtres.
En respectant ces rgles de base pour la conception, votre application satisfait aux exigen-
ces dApple pour sa distribution sur lApp Store et son fonctionnement correspond aux
Figure 3.1
Les interrupteurs
utiliss pour les rglages
de Safari.
iPhone Livre Page 60 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 61
attentes de lutilisateur. Le non-respect de ces concepts risque de conduire au rejet de votre
application par Apple et par ses utilisateurs potentiels.
Section 2 : interfaces fondes sur les listes
et sur Navigateur
Certaines interfaces utilisateur de base pour liPhone se fondent sur les listes pour organiser
lafchage. Lapplication HistoryExample en est un exemple. Dans Dashcode, cette inter-
face est cre de deux manires. La plus rapide consiste utiliser la partie Navigateur.
La partie Navigateur, qui se trouve dans la bibliothque des parties, peut tre dpose
directement sur lapplication pour crer une pile de vues indpendantes. Les vues consti-
tuent lunit dafchage principal avec laquelle les utilisateurs interagissent ; elles sont
souvent appeles, de manire errone, cran. Lorsquune partie Navigateur est ajoute
une application, deux vues sont ajoutes par dfaut, mais pas le code de basculement
dune vue lautre. Une barre den-tte comprenant un bouton de navigation est gale-
ment insre automatiquement. La Figure 3.2 prsente loutil Dashcode aprs lajout de la
partie Navigateur.
Figure 3.2
Ajout dune partie Navigateur dans Dashcode.
iPhone Livre Page 61 Vendredi, 30. octobre 2009 12:04 12
62 Dveloppez des applications pour liPhone
Il est inutile de modier le bouton ajout automatiquement dans len-tte, car la partie
Navigateur ajuste le texte afch pour quil corresponde lintitul de len-tte de la vue
prcdente (si elle existe). Lorsque vous crez une application, vous devez modier le
texte de len-tte, non celui du bouton, pour reter le nom de lapplication ou toute autre
information approprie.
Deux vues avec des noms par dfaut sont insres dans le projet lors de lajout dune
partie Navigateur. En slectionnant longlet Attributs dans linspecteur, vous pouvez
voir ces vues et les renommer. La Figure 3.3 prsente lapplication HistoryExample aprs
avoir nomm les vues mainView et presidentsView. Vous remarquerez les options + et
dans la liste sous-prsentations. Ces boutons vous permettent dajouter dautres vues
et de retirer celles dont vous navez pas besoin.
Toutes les vues de lapplication sont gres depuis la liste sous-prsentations. Vous
remarquerez que, mme si la navigation dans lapplication correspond mainView >
ContinentsView > SouthAmericanView, toutes les vues sont directement des enfants de
stackLayout. Cest ainsi que les applications de ce type doivent tre dveloppes.
Dans les listes rectangulaires arrondies et les listes bout--bout, seul le premier lment de
la liste peut tre slectionn dans lcran Dashcode de conception de linterface graphique.
Figure 3.3
Lapplication HistoryExample avec des vues et deux listes rectangulaires arrondies ajoutes
la vue principale.
iPhone Livre Page 62 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 63
Ce premier lment sert de modle pour les autres lments de la liste. Toute modication
de la couleur, du contenu ou de la taille de cet lment est applique tous les autres
lments de la liste. Cela inclut galement les gestionnaires dvnements affects. Tous
les lments des listes prsentes dans lapplication HistoryExample partagent le mme
gestionnaire dvnements onclick, la fonction changeView.
Le code de la fonction changeView, qui se trouve dans le chier main.js, est donn ci-
aprs. Elle utilise les tiquettes et les valeurs saisies dans lcran des attributs de la vue
pour dterminer la nouvelle vue afcher. Pour examiner cette fonction, slectionnez la
vue, non le premier lment dtiquette. Dans votre application, cest l o vous ajoutez
les lments statiques de la liste (voir Figure 3.4).
function changeView(event)
{
var subViewName = event.target.object.value;
var displayName = event.target.innerText;
var browser = document.getElementById(browser).object;
browser.goForward(subViewName+View, displayName);
}
Figure 3.4
Afchage des attributs de la liste people de la vue principale, avec deux lments statiques ajouts.
iPhone Livre Page 63 Vendredi, 30. octobre 2009 12:04 12
64 Dveloppez des applications pour liPhone
En utilisant ces valeurs et en donnant le nom appropri aux vues, la mthode goForward
de lobjet browser permet de passer la vue suivante. Cette mthode prend deux argu-
ments. Le premier est le nom de la vue vers laquelle basculer, le second, le texte afcher
dans len-tte de la vue. Si vous essayez de basculer vers une vue et si len-tte est modi
sans que la vue change, cela signie que le nom de la vue que vous tentez dafcher ne
correspond pas celui dune vue de votre application.
Lorsque vous crez des applications fondes sur des listes et des vues, vous devez faire
attention lorganisation des donnes. Si les informations sont places dans un trop grand
nombre de vues, lutilisateur trouvera la navigation exagrment complique. En ralit, si
vous ny prenez pas garde, vous pourriez rinventer la navigation de type DOS des annes
1970 et 1980.
Les applications base de listes et de vues ont de nombreuses utilisations, mais elles ne
sont pas toujours les plus attrayantes visuellement. Parfois, le changement de vues doit se
faire partir dun lment autre quune liste.
Section 3 : applications non fondes sur des listes
Bien que les utilisations des applications fondes sur les listes et les vues soient nombreuses,
rien noblige toutes les applications fondes sur les vues utiliser des listes pour accder
aux informations. Dautres indices visuels peuvent indiquer que toucher un lment
permet dafcher des informations supplmentaires. Lapplication PictureExample fournie
avec le framework QuickConnectiPhone en est un exemple.
En indiquant sur lcran quun lment peut tre touch, lutilisateur a tendance toucher
tous les lments pour savoir sils sont actifs. Si vous retenez cette approche, faites atten-
tion ne pas perturber vos utilisateurs par ces indices ou par les lments quils doivent
toucher pour contrler votre application.
Le code suivant prsente deux diffrences par rapport au code prcdent. Tout dabord,
chacune des images a besoin dun gestionnaire onclick ou ontouchstart pour dclen-
cher le passage une vue secondaire. Dans cet exemple, une seule fonction, goSub, est
utilise pour grer les images touchables.
function goSub(event)
{
var stackLayout = document.getElementById(stackLayout).object;
stackLayout.setCurrentView(event.target.id+View, false);
}
iPhone Livre Page 64 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 65
En affectant chaque image un id semblable au nom de la vue quil reprsente, il est
facile demployer une mthode pour changer de vue. Lexemple prcdent le montre,
lobjet stackLayout offre une mthode setCurrentView qui prend deux arguments :
lidentiant de la vue vers laquelle basculer et un indicateur. Si lindicateur vaut true,
cela signie que le changement de vue correspond un retour en arrire. Lidentiant et
lindicateur permettent au programmeur de contrler les transitions dune vue une
autre.
Contrairement lapplication HistoryExample constitue de listes, de vues et dun en-tte
de navigation prconstruits, lapplication PictureExample ne comprend aucune barre de
navigation automatique. Cest pourquoi le programmeur doit crire le code de retour dune
vue secondaire la vue principale.
Les images de retour (marques par Back) dans les vues secondaires sont faites pour reve-
nir la vue principale. Puisquil ne serait pas appropri que leffet visuel associ une
transition en arrire soit identique celui dune transition en avant, la valeur du second
paramtre de la fonction setCurrentView est xe true. Il indique une transition
visuelle en arrire.
Le code de goMain prsent ci-aprs est associ au bouton Retour en tant que gestionnaire
onclick. Puisque le second argument vaut true, la transition associe mainView se fait
dans un sens oppos au comportement standard. Nous pouvons ainsi faire en sorte que
lutilisateur pense quune action prcdente est annule.
function goMain(event)
{
// Fixez la vue courante dun StackLayout.
var stackLayout = document.getElementById(stackLayout).object;
stackLayout.setCurrentView(mainView, true);
}
Par rapport aux applications fondes sur une partie Navigateur, lanimation du change-
ment de vues offre dautres possibilits. Elle constitue un autre lment dinformation
donn lutilisateur. Lorsque lanimation utilise pour passer une vue nest pas identi-
que celle employe pour dautres vues, lutilisateur sait que cette vue a quelque chose de
diffrent. La Figure 3.5 prsente la liste des vues secondaires et la fonction goMain dans
Dashcode.
iPhone Livre Page 65 Vendredi, 30. octobre 2009 12:04 12
66 Dveloppez des applications pour liPhone
Comme le montre le Tableau 3.2, il est possible dutiliser plusieurs types de transitions
dans une application, mais ce nest pas judicieux.
Figure 3.5
Longlet des attributs de stackLayout montre les options de la transition.
Tableau 3.2 : Transitions par dfaut disponibles dans Dashcode
Type de transition Comportement
Dler Une transition bidimensionnelle dans laquelle la nouvelle vue afcher arrive dans
la zone visible pendant que lancienne vue la quitte.
Dissolution Une transition bidimensionnelle dans laquelle la vue afcher devient plus opa-
que tandis que lancienne vue devient plus transparente. Puisquelles se super-
posent, lancienne vue semble se transformer progressivement en la nouvelle
vue.
iPhone Livre Page 66 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 67
Si lon en croit linterface de Dashcode, il semble que les seules directions possibles pour
ces transitions soient de droite gauche et de gauche droite, mais ce nest pas le cas. Des
mouvements de haut en bas et de bas en haut sont galement possibles.
Le code suivant est extrait du chier setup.js de lapplication HistoryExample ; il a t
gnr par Dashcode. Vous le constatez, les types de transitions et leur direction sont indi-
qus pour toutes les vues. Si vous souhaitez les modier, vous devez tout dabord dsac-
tiver la gnration de code en allant dans le menu Prsentation > Arrter le gnrateur de
code.
var dashcodePartSpecs = {
...
Diapositive Une transition bidimensionnelle semblable Dler. Dans ce cas, lancienne vue
reste sa place pendant que la nouvelle apparat et la recouvre, pour donner luti-
lisateur limpression dune pile de vues. Dans ce cas, une transition "en arrire" cor-
respond entrer dans les dtails des vues de lapplication, tandis quune transition
"en avant" correspond un retour vers le dbut de la pile.
Fondu Une transition bidimensionnelle semblable Dissolution. Dans ce cas, lancienne
vue reste opaque an que les deux vues soient visibles la n de la transition.
Lorsque cette transition se fait "en arrire", la nouvelle vue devient opaque et la
vue dorigine est intgralement afche. Cette transition sert ajouter une nou-
velle information ou fonctionnalit une vue existante, car les deux vues peuvent
accepter les vnements de toucher.
Rotation Une transition tridimensionnelle qui provoque une rotation le long de laxe Y de
lappareil par rapport au centre de lancienne et de la nouvelle vue. Lutilisateur a
limpression que lancienne vue se trouve au premier plan de lapplication et que la
nouvelle se trouve larrire-plan. Cette transition nest gnralement pas utilise
dans les applications qui comprennent uniquement deux vues.
Cube Une transition tridimensionnelle dans laquelle lutilisateur voit toutes les vues sur
les cts dun cube, qui pivote vers lavant ou larrire.
changer Une transition tridimensionnelle dans laquelle lancienne vue semble glisser
depuis un ct et passer sous la nouvelle vue. Au cours de la transition, larrire-
plan de la nouvelle vue est transparent. la n de la transition, cet arrire-plan
devient opaque.
Faire pivoter Une transition tridimensionnelle dans laquelle lancienne et la nouvelle vue pivotent
autour de laxe Y de lappareil sur un des bords. Leffet obtenu est comparable une
porte pivotante.
Tableau 3.2 : Transitions par dfaut disponibles dans Dashcode (suite)
Type de transition Comportement
iPhone Livre Page 67 Vendredi, 30. octobre 2009 12:04 12
68 Dveloppez des applications pour liPhone
"stackLayout": { "creationFunction": "CreateStackLayout",
"subviewsTransitions": [{ "direction": "right-left", "duration": "", "timing":
"ease-in-out", "type": "push" }, { "direction": "right-left","duration": "",
"timing": "ease-in-out", "type": "push" }, { "direction": "right-left",
"duration": "", "timing": "ease-in-out", "type": "push" }, { "direction":
"right-left", "duration": "", "timing": "ease-in-out", "type": "push" }, {
"direction": "right-left", "duration": "", "timing": "ease-in-out", "type":
"push" }] }
...
};
Puisque Dashcode gnre une grande partie du code votre place et remplace rgulire-
ment le contenu du chier setup.js, vous ne devez pas modier celui-ci tant que lapplica-
tion nest pas termine. Il est plus facile deffectuer ces modications aprs que le chier a
t plac dans le modle QuickConnectiPhone pour Xcode car Dashcode nentre plus en
jeu et ne peut donc pas craser les modications que vous effectuez.
Le code prcdent contient la dclaration de quatre objets JavaScript. Chacun commence
par le caractre {, se termine par } et contient les attributs direction, duration, timing
et type. Lun de ces objets, le deuxime, est prsent en gras an de le distinguer des
autres.
Chacun de ces objets anonymes dnit le comportement du passage dune vue une autre.
Lobjet prsent en gras dclare une transition de type Dler (voir Tableau 3.2). Elle
pousse la nouvelle vue de la gauche vers la droite avec une acclration au dbut de la
transition et un ralentissement la n (synchronisation ease-in-out).
Les autres options de synchronisation sont ease-in, ease-out et par dfaut. La synchro-
nisation par dfaut, dans laquelle la vitesse est constante, est utilise lorsque lattribut
timing de lobjet de dnition est absent.
Nous lavons mentionn prcdemment, il existe dautres options pour lorientation de la
transition : de haut en bas (top-bottom) et de bas en haut (bottom-top). Elles sont valides
uniquement pour les transitions de type Diapositive et Dler.
Si vous choisissez de modier les dclarations de ces objets, sachez que cela peut
provoquer des problmes dans une application plus complexe. Il semble quApple ait
interdit certains choix dans les options de transition car ils provoquent des dysfonction-
nements dans le moteur WebKit de Safari et dans lobjet UIWebView des applications
hybrides.
iPhone Livre Page 68 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 69
Section 4 : applications dimmersion
Les applications dimmersion sont en rupture totale avec lutilisation des vues pour
regrouper des informations et des contrles. Les jeux en sont la concrtisation la plus
frquente, mais certaines applications mdicales pour liPhone suivent galement cette
voie. Lide est que les interactions de lutilisateur avec lapplication soient naturelles,
uides et, si possible, dans une seule vue.
Si les jeux utilisent cette approche sous sa forme extrme, elle peut galement tre
employe dautres manires. Cest notamment le cas dans les applications dimagerie
mdicale, o les possibilits tactiles de liPhone changent normment la manire dont les
mdecins interagissent avec les images.
Il ny a aucune raison pour que des dveloppeurs novateurs nappliquent pas cette solution
des applications dentreprise ou scientiques. Souvent, de mauvaises dcisions mtier
sont prises car lafchage des lments dinformation connexes et complexes avec les
graphiques actuels est difcile. Pour examiner les donnes de manire diffrente, il faut
utiliser une autre forme dafchage.
Si des donnes peuvent tre prsentes sous forme non linaire sur lintgrit de lcran,
des informations complmentaires peuvent leur tre superposes an didentier des rela-
tions. Une version simple de cette mthode est employe dans les applications cartogra-
phiques pour non seulement afcher une route menant dun lieu un autre, mais
galement indiquer la densit du trac sur cette route et les routes voisines. Les deux
lments dinformation sont superposs an que lutilisateur puisse en dduire un motif
utile.
Cet ouvrage ne prtend pas fournir une solution pour la manipulation des donnes en vue
de leur afchage. Il suggre simplement que cette possibilit existe et quelle est
employe. Dans cette section, nous prendrons lexemple dun jeu.
Le jeu DollarStash est une variante de lapplication web Leaves dApple. Dans cette appli-
cation, des images de feuilles sont ajoutes sur la page et tombent progressivement vers le
bas de lcran en tourbillonnant. Pour en faire un jeu, nous remplaons les feuilles par des
images de billets.
Lorsque lutilisateur touche un billet, la quantit dargent sur son compte est incrmente.
Si un billet disparat totalement avant que lutilisateur ne le touche, le solde du compte est
dcrment. Des groupes de billets sont afchs par vagues en haut de lcran. Chaque
vague contient un billet de plus que la prcdente. Lorsque le solde du joueur tombe sous
zro, la partie est termine. La Figure 3.6 montre le jeu en cours dexcution. Mme sil a
t dvelopp rapidement, il rvle les limites des applications de ce type dans un environ-
nement hybride.
iPhone Livre Page 69 Vendredi, 30. octobre 2009 12:04 12
70 Dveloppez des applications pour liPhone
Comme dautres applications, UIWebView utilise le moteur WebKit de Safari pour afcher
le contenu lcran. Ce moteur, et dautres comme lui, a normment volu ces dernires
annes. Toutefois, lorsque le processeur est fortement sollicit, quelques vnements de
linterface utilisateur, comme les clics et les touchers, sont ignors. Si vous jouez au jeu
DollarStash sur votre appareil, non le simulateur, vous le constaterez rapidement.
Plus le nombre de billets augmente, plus le nombre de touchers ignors par le moteur
augmente. En soumettant lutilisateur un tel dsagrment, vous ne respectez pas une
rgle fondamentale de la conception de linterface utilisateur mentionne dans la premire
section de ce chapitre : la rponse aux actions de lutilisateur doit tre rapide.
Pour les portions fortement interactives des applications de ce type, il est prfrable
dutiliser Objective-C. Cela ne signie pas que les applications ne puissent pas utiliser
UIWebView pour la mise en page de textes et un afchage simple dimages. Cela signie
que, jusqu ce que la puissance des processeurs des iPhone et des iPod Touch augmente
signicativement, il ne faut pas utiliser les transformations et les animations CSS (Cascading
Style Sheet) natives pour la cration de jeux complexes.
En connaissant les limites de lappareil, il est possible dopter pour une meilleure concep-
tion. Si les jeux gourmands en ressources processeur ne sont pas vraiment viables dans des
applications hybrides, lutilisation des transformations et des animations CSS pour raliser
le glisser-dposer, le redimensionnement et la rotation dun seul lment de linterface la
fois est tout fait envisageable.
Figure 3.6
Le jeu DollarStash
en cours dexcution.
iPhone Livre Page 70 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 71
Section 5 : crer et utiliser des transformations CSS
personnalises
Cette section explique comment crer des possibilits de glisser-dposer, de redimension-
nement et de rotation en se fondant sur les nouvelles transformations CSS intgres au
moteur WebKit. Pour de plus amples informations concernant les transitions, les transfor-
mations et les animations CSS, consultez le guide des effets visuels avec Safari ladresse
http://developer.apple.com/safari/library/documentation/InternetWeb/Conceptual/
SafariVisualEffectsProgGuide/Introduction/Introduction.html.
Plusieurs mises en uvre JavaScript du glisser-dposer sont disponibles en tlchar-
gement. Si elles sont parfaitement adaptes une utilisation multinavigateur sur les machines
de bureau, elles sont inefcaces sur les iPhone et les iPod Touch, car elles demandent des
ressources processeur trop importantes. Une bonne alternative consiste employer les
transformations CSS.
WebKit, le moteur utilis par Safari et la classe UIWebView dans les applications hybrides,
est capable de prendre en charge les transitions dnies en CSS. Elles bncient en effet
dune acclration matrielle, ce qui les rend plus efcaces que des modications
programmes en JavaScript comme dans les autres bibliothques.
Prenons comme exemple simple le dcalage vers le bas de la position dune balise HTML
<div>. Dans une version JavaScript classique, il faut modier lattribut top du style de la
balise. Supposons quune classe CSS soit affecte au <div> et que la valeur de lattribut
top soit gale 50 pixels. Un dcalage vers le bas de 50 pixels supplmentaires sobtient
en xant ce mme attribut 100 pixels :
unDiv.style.top = 100px;
Cette dclaration est interprte comme une commande JavaScript et elle est excute par
le moteur la mme vitesse et en utilisant les mmes ressources processeur que nimporte
quelle autre commande JavaScript. La transformation CSS quivalente fonctionne diff-
remment.
En utilisant les transformations CSS pour obtenir ce dcalage de 50 pixels par rapport la
position dorigine dclare, il faut galement employer une dclaration du style pour le
<div>. Toutefois, dans ce cas, nous utilisons un attribut totalement diffrent.
webkitTransform fait partie des nouveaux attributs ajouts aux classes CSS et, par cons-
quent, lattribut style de lobjet JavaScript Element. En lui donnant la bonne valeur, des
fonctions natives bnciant dune acclration matrielle sont invoques. Puisquil nest
iPhone Livre Page 71 Vendredi, 30. octobre 2009 12:04 12
72 Dveloppez des applications pour liPhone
pas interprt comme du JavaScript, toute modication de lattribut CSS dni est excute
beaucoup plus rapidement que le code JavaScript quivalent de lexemple prcdent.
La transformation requise ici ne demande quune seule ligne de code :
unDiv.style.webkitTransform = translateY(50px);
premire vue, lattribut de transformation ressemble un pointeur de fonction, comme
onclick, ontouch et dautres gestionnaires dvnements, mais ce nest pas le cas.
La principale diffrence entre webkitTransform et les gestionnaires rside dans le fait
quaucune fonction JavaScript dclare en ligne ou comme une fonction de Window nest
affecte. la place, une chane dcrivant la fonction standard invoquer et ses paramtres
est utilise. Cette chane est ensuite analyse par le moteur WebKit dans une partie de son
code distincte de celle qui interprte les instructions JavaScript.
Notez galement que le dcalage indiqu est relatif lemplacement dorigine du <div>.
Pour dcaler un Element de 50 pixels supplmentaires vers le bas, nous passons trans-
lateY le paramtre 50px. Il est galement important de comprendre que la dnition de
lemplacement initial na pas chang. La valeur dorigine de lattribut top du <div> est
toujours gale 50px. Seul lemplacement auquel il est afch a chang. Si, aprs le
dplacement, vous consultez lattribut top de lobjet, vous obtenez toujours la valeur
50px, non 100px.
Lapplication Drag montre comment mouvoir un <div> sur lcran en utilisant une fonc-
tion de dplacement. Pour cela, des gestionnaires ontouchstart, ontouchchange et
ontouchend sont associs au <div> dplac.
Les vnements de toucher diffrent des vnements onclick, onmousedown, onmouse-
move et onmouseup standard utiliss dans les implmentations JavaScript classiques du
glisser-dposer. Puisquun toucher peut tre constitu de deux touchers individuels, ou
plus, par exemple lorsque lutilisateur pose deux ou trois doigts sur lcran, un vnement
de toucher doit contenir des informations concernant chacun deux.
Chaque toucher individuel et ses informations sont enregistrs dans le tableau target-
Touches, qui est un attribut de lobjet event. Ce tableau est dimensionn daprs le
nombre de doigts pos sur llment par lutilisateur. Sa taille est donc gale un
lorsquun doigt est pos, deux, lorsque deux doigts sont utiliss.
Chaque objet enregistr dans le tableau est de type Touch et comprend de nombreux attri-
buts gnralement associs un vnement de la souris en JavaScript. Le Tableau 3.3
recense ces attributs.
iPhone Livre Page 72 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 73
La mise en uvre du glisser-dposer propose se fonde sur les attributs clientX et
clientY car le dlement nest pas autoris dans lapplication dexemple. Dans le cas
contraire, il faudrait utiliser les attributs pageX et pageY.
Les lments "sautillants" qui apparaissent lorsque le glisser-dposer dbute posent un
problme. Ce sautillement se produit car lutilisateur a slectionn lobjet en le touchant
quelque part lintrieur de son contour alors que le dplacement est appliqu au coin
suprieur gauche. Si cette discordance nest pas gre, le coin suprieur gauche de lobjet
que lutilisateur fait glisser "saute" lemplacement de son doigt au dbut de lopration.
videmment, lutilisateur considre ce comportement comme anormal. Par exemple, sil
slectionne le centre de lobjet pour dbuter lopration, il peut raisonnablement sattendre
ce que son doigt reste au centre de lobjet pendant lopration. La Figure 3.7 illustre le
fonctionnement de lapplication Drag.
Pour remdier ce problme, lapplication affecte la fonction setStartLocation au
gestionnaire JavaScript ontouchstart. Cette fonction, extraite du chier main.js et repro-
duite ci-aprs, obtient et enregistre la position du toucher dorigine, en pixels, par rapport
au coin suprieur gauche de la fentre de lapplication.
1 function setStartLocation(event)
2 {
3 var element = event.target;
4 element.offsetX = event.targetTouches[0].clientX;
5 element.offsetY = event.targetTouches[0].clientY;
6 }
Tableau 3.3 : Attributs de la classe Touch
Attribut Description
pageX Le dcalage horizontal partir du bord gauche du document, y compris les informations de
dlement horizontal
pageY Le dcalage vertical partir du bord suprieur du document, y compris les informations de d-
lement vertical
screenX Le dcalage horizontal partir du bord gauche de lcran de lappareil
screenY Le dcalage vertical partir du bord suprieur de lcran de lappareil
clientX Le dcalage horizontal partir du bord gauche de la fentre de lapplication
clientY Le dcalage vertical partir du bord suprieur de la fentre de lapplication
target Lobjet du DOM qui reprsente llment HTML qui a t touch
iPhone Livre Page 73 Vendredi, 30. octobre 2009 12:04 12
74 Dveloppez des applications pour liPhone
En enregistrant cette distance dans les attributs offsetX et offsetY de llment touch,
nous pouvons ensuite lutiliser pendant le dplacement de llment de manire emp-
cher le sautillement. Le dplacement de llment se produit non pas dans la fonction
setStartLocation, mais dans la fonction drag dnie comme gestionnaire ontouch-
change. Cette fonction se trouve galement dans le chier main.js.
La ligne 3 de la fonction drag donne ci-aprs est indispensable toute mise en uvre du
glisser-dposer pour liPhone et liPod Touch. Normalement, lorsquun vnement de type
modication du toucher est dclench, le navigateur Safari ou UIWebView procde un
dlement. Pour dsactiver ce comportement standard, nous invoquons la mthode
preventDefault de event. Lorsque cette mthode est invoque dans le gestionnaire
ontouchchange, la vue ne dle pas si le doigt est dplac dans llment auquel le
gestionnaire est affect.
tant dbarrass du dlement par dfaut, vous pouvez modier lemplacement auquel
llment est afch en utilisant webkitTransform. Pour cela, lemplacement du toucher
actuel doit tre obtenu et compar lemplacement du toucher initial enregistr par la
fonction setStartLocation.
1 function drag(event)
2 {
3 event.preventDefault();
Figure 3.7
Lapplication Drag aprs
le dplacement du <div>
vert.
iPhone Livre Page 74 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 75
4 var element = event.target;
5 element.x = event.targetTouches[0].clientX
6 - event.target.offsetX;
7 element.y = event.targetTouches[0].clientY
8 - event.target.offsetY;
9 if(element.lastX || element.lastY){
10 element.x += element.lastX;
11 element.y += element.lastY;
12 }
13 element.style.webkitTransform = translate(
14 + element.x + px,
15 + element.y + px);
16 }
Le code des lignes 5 8 calcule les dcalages de la position de llment selon les axes X
et Y. Ces rsultats, en pixels, sont enregistrs dans les attributs x et y de llment courant
en vue de leur utilisation ultrieure, cest--dire aux lignes 13 15 pour modier laf-
chage laide de la fonction translate dcrite prcdemment.
Puisquil est possible que ce glisser ne soit pas le premier effectu par lutilisateur sur un
lment, il est ncessaire de conserver les dplacements raliss prcdemment. Le dpla-
cement se fait aux lignes 9 11 du code prcdent et les dcalages sont enregistrs dans la
mthode done ci-aprs, qui est dnie comme gestionnaire ontouchend.
function done(event)
{
var element = event.target;
element.lastX = element.x;
element.lastY = element.y;
}
La mthode done existe pour une seule raison : enregistrer le dcalage actuel pour le
retrouver si lutilisateur venait dplacer nouveau llment. Pour cela, elle enregistre
les attributs x et y actuels de llment dans les attributs lastX et lastY. Ainsi, nous
sommes certains de pouvoir en disposer chaque dclenchement des vnements ontouch-
change lorsque lutilisateur dplace son doigt sur lcran.
En affectant ces trois mthodes en tant que gestionnaires aux lments de linterface, ils
peuvent tre dplacs par lutilisateur de manire simple. la section suivante, vous
verrez comment crer et utiliser un module de glisser-dposer moins naf et plus simple
demploi.
Outre le glisser-dposer, les applications pour liPhone ont souvent besoin dune possibi-
lit de redimensionnement et de rotation des lments de linterface. Ces lments peuvent
tre des <div>, des boutons, des images ou tout autre lment dorganisation ou graphique.
iPhone Livre Page 75 Vendredi, 30. octobre 2009 12:04 12
76 Dveloppez des applications pour liPhone
Le code ncessaire la mise en uvre de ces fonctionnalits est plus court que celui du
glisser-dposer. Il semble vident quApple a voulu que les dveloppeurs incluent ces
comportements dans leurs applications.
Les applications dillustration du traitement des gestes montrent que le redimension-
nement et la rotation sont faciles raliser. la place des touchers, elles utilisent des gestes
(gesture). Les gestes diffrent des touchers en cela quils supposent toujours que plusieurs
doigts sont employs, par exemple lors dun pincement.
Pour reprsenter ces gestes, un GestureEvent est pass tout gestionnaire de gestes.
Puisque cette classe reprsente un geste, elle ne comprend aucune information de position
comme la classe TouchEvent. En revanche, elle transmet trois lments dinformation
importants recenss au Tableau 3.4.
Lapplication dillustration du traitement des gestes utilise trois vnements pour redimen-
sionner et faire pivoter un <div>. Pour cela, nous ajoutons au <div> un gestionnaire
ongesturechange nomm changeIt. Pour ajouter des gestionnaires dvnements, utilisez
longlet Comportements de linspecteur. Voici le code de la mthode changeIt :
function changeIt(event)
{
event.preventDefault();
var element = event.target;
element.style.webkitTransform=
rotateZ(+event.rotation
+deg) scale(+event.scale+);
}
Tableau 3.4 : Les attributs importants de GestureEvent
Attribut Description
scale Une valeur relle positive ou ngative qui reprsente le changement de la distance
sparant les deux doigts utiliss dans un geste. Les valeurs ngatives indiquent que les
doigts se sont croiss. Cet attribut est utilis dans la gestion du pincement.
rotation Une valeur relle positive ou ngative qui indique, en degrs, la diffrence angulaire
entre les positions des deux doigts utiliss dans un geste et une ligne verticale.
Cet attribut est utilis dans la gestion des rotations.
target Lobjet du DOM qui reprsente llment HTML concern par le geste.
iPhone Livre Page 76 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 77
linstar de lapplication Drag, le comportement par dfaut associ lvnement doit
tre dsactiv de manire empcher le dlement. Mais, contrairement Drag, les infor-
mations de rotation et de redimensionnement ne sont pas enregistres. Il est inutile denre-
gistrer les informations de rotation car elles sont relatives une ligne de base, non lobjet
transform.
Les informations de redimensionnement doivent tre enregistres pour tre utilises
lors du geste suivant, car elles sont relatives llment transform et se cumulent.
Cette sauvegarde nest pas effectue dans notre exemple car nous voulons illustrer le
dysfonctionnement correspondant. La section suivante montre comment les enregistrer et
les rutiliser.
Notez que deux fonctions sont employes dans la chane qui dnit la commande de
webkitTransform. Cela permet deffectuer la rotation et le redimensionnement du <div>
en un seul appel. Rien ne vous empche de les sparer et de les invoquer de manire condi-
tionnelle.
Vous disposez de trois fonctions de rotation pour votre application. Chacune fait pivoter
llment autour de lun des axes du tlphone. Laxe X est horizontal, laxe Y est vertical
et laxe Z sort de lcran. Dans le code prcdent, nous choisissons rotateZ pour que le
<div> pivote sur le plan X-Y de lappareil (voir Figure 3.8).
Figure 3.8
Application de la fonction
rotateZ de webkitTransform.
iPhone Livre Page 77 Vendredi, 30. octobre 2009 12:04 12
78 Dveloppez des applications pour liPhone
Il est trs facile de modier la faon dont le <div> pivote. En utilisant rotateY, il pivote
selon laxe Y et semble devenir plus troit avant dafcher son verso. Si vous utilisez
rotateX, il pivote le long de laxe X et semble rapetisser avant dafcher son verso.
Vous pourriez penser une mise en uvre de type Cover Flow laide de la rotation. Au
moment de lcriture de ces lignes, elle est dconseille. En effet, le nombre de transfor-
mations ncessaires un tel comportement va solliciter normment le processeur de
liPhone ou de liPod Touch et lutilisateur risque dtre du.
Puisque vous connaissez prsent les implmentations naves du glisser-dposer, du redi-
mensionnement et de la rotation, vous tes en mesure de comprendre un module sophistiqu
qui propose ces fonctionnalits.
Section 6 : crer et utiliser un module de glisser-
dposer, de redimensionnement et de rotation
Tel quil est expliqu au Chapitre 2, les modules sont indpendants et mettent en uvre
lintgralit dune fonctionnalit. Autrement dit, ils sont faiblement coupls au reste du
code dune application et afchent une cohsion forte. Les modules bien conus fournis-
sent toujours une API. Celle que nous allons implmenter dans cette section est dcrite au
Tableau 3.5.
Tableau 3.5 : API de glisser-dposer, redimensionnement et rotation
Fonction Paramtres Description
makeDraggable element (obligatoire) llment du
DOM cible du glissement.
startDragCmd (facultatif) une
commande associe aux fonctions de
contrle invoques la n de lvne-
ment ontouchstart.
Cette fonction congure les gestionnaires
dvnements sur llment indiqu an
que lutilisateur puisse le faire glisser.
dragCmd (facultatif) une commande
associe aux fonctions de contrle
invoques la n de tous les vne-
ments ontouchmove.
dropCmd (facultatif) une commande
associe aux fonctions de contrle
invoques la n de lvnement
ontouchend.
iPhone Livre Page 78 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 79
Dans votre code, vous devez simplement invoquer ces deux fonctions pour que lutilisa-
teur dispose des fonctionnalits de glisser-dposer, de redimensionnement et de rotation
(voir Figure 3.9). Lapplication dragAndGesture se trouve dans le rpertoire Examples du
paquetage QuickConnectiPhone tlcharg. Les fonctions sont dnies dans le chier
QCUtilities.js fourni par le framework.
Voici le code de la fonction load dnie dans le chier main.js. Il montre comment utiliser
ces fonctions avec des lments de linterface utilisateur.
function load()
{
...
var anElement = document.getElementById(button);
makeDraggable(anElement);
makeChangeable(anElement);
anElement = document.getElementById(imageBox);
makeDraggable(anElement);
makeChangeable(anElement);
anElement = document.getElementById(box);
makeDraggable(anElement);
makeChangeable(anElement);
anElement = document.getElementById(stuff);
makeDraggable(anElement);
}
makeChangeable element (obligatoire) llment du
DOM cible du redimensionnement et
de la rotation.

startChangeCmd (facultatif) une
commande associe aux fonctions de
contrle invoques la n de lvne-
ment ongesturestart.
Cette fonction congure les gestionnaires
dvnements sur llment indiqu an
que lutilisateur puisse le redimensionner
et le faire pivoter autour de laxe Z.
dragCmd (facultatif) une commande
associe aux fonctions de contrle
invoques la n de tous les vne-
ments ongesturechange.
doneChangeCmd (facultatif) une
commande associe aux fonctions de
contrle invoques la n de lvne-
ment ongestureend.
Tableau 3.5 : API de glisser-dposer, redimensionnement et rotation (suite)
Fonction Paramtres Description
iPhone Livre Page 79 Vendredi, 30. octobre 2009 12:04 12
80 Dveloppez des applications pour liPhone
Dans cet exemple, trois lments de linterface sont modis an que lutilisateur puisse
les faire glisser, les redimensionner et les faire pivoter ; le quatrime pourra seulement tre
dplac. Aprs avoir obtenu une rfrence llment de linterface, elle est passe aux
fonctions de lAPI. Cela suft pour que les lments de linterface utilisateur deviennent
actifs.
Les mises en uvre naves du glisser-dposer, du redimensionnement et de la rotation
dcrites prcdemment dans cette section fonctionnent indpendamment lune de lautre.
Lexemple ci-dessus montre quelles doivent pouvoir oprer de concert. Pour cela, elles
doivent connatre leffet, sil existe, que les autres fonctions ont appliqu llment.
La modication requise commence dans les fonctions makeDraggable et makeChangeable.
La fonction makeDraggable de lAPI prend en charge la conguration et la gestion du
gestionnaire ontouchstart, ainsi que les commandes passes excuter aprs lvnement.
function makeDraggable(anElement, startDragCmd, dragCmd, dropCmd){
anElement.ontouchstart = prepareDrag;
anElement.isDraggable = true;
if(startDragCmd){
anElement.startDragCmd = startDragCmd;
}
Figure 3.9
Lapplication dragAnd-
Gesture en cours
dexcution, avec un
lment dplac et pivot.
iPhone Livre Page 80 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 81
if(dragCmd){
anElement.dragCmd = dragCmd;
}
if(dropCmd){
anElement.dropCmd = dropCmd;
}
}
Vous remarquerez que lattribut isDraggable de llment est x true. Il sagit de la
premire information que nous devons enregistrer pour que les fonctionnalits puissent
cohabiter. Notez galement quun seul gestionnaire de toucher, ontouchstart, est affect
dans cette fonction. En effet, nous voulons ignorer les touchers lorsquun lment est redi-
mensionn ou pivot ; nous y reviendrons plus loin dans cette section.
La fonction makeChangeable est comparable. Elle affecte les gestionnaires de gestes, xe
lattribut isChangeable true et enregistre les commandes qui devront tre excutes
aprs lvnement. Contrairement la fonction makeDraggable, elle xe les gestionnaires
de gestes. En effet, lorsque des vnements de toucher sont dclenchs suite au toucher
simple dun glissement, aucun vnement de geste nest dclench. Si un lment est
dplaable et que le glissement se produise, les vnements de toucher sont dclenchs et
sont traits. Si un lment est modiable et quun geste se produise, les vnements de
toucher et de geste sont dclenchs, les vnements de toucher sont ignors et les vnements
de geste sont traits.
function makeChangeable(anElement, startChangeCmd, changeCmd, doneChangeCmd){
anElement.ongesturestart = prepareGesture;
anElement.ongesturechange = changeIt;
anElement.ongestureend = gestureDone;
anElement.isChangeable = true;
anElement.oldRotation = 0;
anElement.oldScale = 1;
anElement.startChangeCmd = startChangeCmd;
anElement.changeCmd = changeCmd;
anElement.doneChangeCmd = doneChangeCmd;
}
Deux autres paramtres sont initialiss dans la mthode makeChangeable. Il sagit des
attributs de mmorisation du redimensionnement et de la rotation nomms oldScale et
oldRotation.
Dans lapplication gestures, chaque fois que llment est pivot ou redimensionn, il
commence par reprendre sa taille dorigine, car le redimensionnement effectu prcdem-
ment nest pas mmoris automatiquement. Lattribut oldScale de llment permet de
rsoudre ce problme de taille.
iPhone Livre Page 81 Vendredi, 30. octobre 2009 12:04 12
82 Dveloppez des applications pour liPhone
Lattribut oldScale est initialis 1, car le redimensionnement correspond un multipli-
cateur appliqu la largeur et la hauteur de llment ; nous y reviendrons plus loin dans
cette section. Si le multiplicateur est suprieur ou gal 0 et infrieur 1, llment est rduit.
Si le multiplicateur est gal 1, llment reste inchang. Si le multiplicateur est suprieur
1, llment est agrandi.
Lorsquun lment a dj t redimensionn, le facteur utilis doit tre combin au
nouveau multiplicateur pour obtenir la taille correcte de llment. Par exemple, si le
premier redimensionnement de llment avait doubl sa taille, la valeur de oldScale doit
tre gale 2. Si lutilisateur pince llment de manire le rduire de 10 %, le nouveau
facteur de redimensionnement doit tre gal 2 0,9, cest--dire 1,8. Si la valeur de
oldScale ntait pas conserve, la taille de llment serait xe 0,9 et ne correspondrait
pas aux intentions de lutilisateur.
Prcdemment, la fonction prepareDrag tait affecte au gestionnaire dvnements
ontouchstart. Cette fonction, dont le code est donn ci-aprs, contient plusieurs points
intressants. Tout dabord, un tableau dobjets Touch est enregistr. Ainsi, les fonctions de
traitement des vnements de geste peuvent accder aux informations de toucher pertinen-
tes. Par exemple, il peut tre ncessaire de connatre le nombre de touchers qui ont provo-
qu lvnement de geste. Cette information nest pas disponible dans les vnements
passs aux gestionnaires de gestes.
1 function prepareDrag(event){
2 stopDefault(event);
3 this.touches = event.targetTouches;
4 var self = this;
5 this.timeOut = setTimeout(function(){
6 if(self.changing){
7 return;
8 }
9 self.dragging = true;
10 self.ontouchmove = dragIt;
11 self.ontouchend = dragDone;
12 self.offsetX = event.targetTouches[0].clientX;
13 self.offsetY = event.targetTouches[0].clientY;
14 self.oldZIndex = self.style.zIndex;
15 self.style.zIndex = 50;
16 if(self.startDragCmd){
17 var params = new Array();
18 params.push(event);
19 params.push(self);
20 handleRequest(self.startDragCmd, params);
21 }
22 }, 75);
23 }
iPhone Livre Page 82 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 83
Un autre point intressant du code prcdent se trouve la ligne 5. Au lieu denregistrer
immdiatement la position initiale du toucher dans les attributs offsetX et offsetY de
llment cible du glissement, une minuterie retarde laffectation de ces valeurs et
dautres. Nous procdons ainsi, car la fonction prepareDrag peut avoir t appele suite
un geste effectu par lutilisateur.
Les vnements de toucher dclenchs par des gestes surviennent toujours avant les
vnements de geste dclenchs. Si lvnement pass prepareDrag vient effectivement
dun geste, les gestionnaires ontouchmove et ontouchend ne doivent pas tre xs pour
viter quils ne soient appels lorsque le geste change et lorsquil se termine. Si ces deux
gestionnaires taient invoqus, ils produiraient un comportement de glissement et provo-
queraient un dysfonctionnement du comportement associ au geste.
La minuterie dnie doit tre sufsamment longue pour que la fonction prepareGesture
gestionnaire du geste soit appele. En effet, elle met jour lattribut changing de
llment en cours de modication.
La ligne 22 montre que le retard est de 75 millisecondes. Cela suft pour que le gestion-
naire de geste soit invoqu et excut si un geste se produit, tout en restant sufsamment
court pour que lutilisateur ne soit pas gn dans le cas dun glissement. Si la minuterie est
trop longue, lutilisateur risque davoir fait glisser son doigt en dehors de llment avant
que celui-ci ne se dplace.
Le dernier point intressant concerne le remplissage du tableau params et lappel
handleRequest. Linvocation de la fonction handleRequest la ligne 20 permet de crer
des fonctions diffres dont lexcution a lieu chaque fois quun vnement de toucher
correspond un glissement. Ces fonctions diffres sont dnies laide des fonctions
mapCommandTo* fournies dans le chier mappings.js (voir Chapitre 2). Vous pouvez appe-
ler autant de fonctions de contrle mtier (BCF, Business Control Function) et de fonc-
tions de contrle de lafchage (VCF, View Control Function) que vous le souhaitez
lorsque le glissement dbute. Par exemple, vous pouvez les utiliser pour retirer llment
de son parent, modier sa couleur darrire-plan ou ses bordures, etc.
Puisque rien nindique comment et si vous utiliserez ces fonctions diffres, certaines
informations sont places dans le tableau param. Comme le montre le code prcdent, ce
tableau comprend llment dplac et lvnement correspondant. Ces informations ne
seront peut-tre pas utiles dans les fonctions diffres que vous allez crer, mais elles sont
votre disposition en cas de besoin.
Lorsque lutilisateur dplace son doigt sur lcran, le gestionnaire dragIt de lvnement
ontouchmove est invoqu de manire rpte. linstar de la fonction drag de lapplica-
tion Drag, cette fonction prend en charge le dplacement de llment conformment au
iPhone Livre Page 83 Vendredi, 30. octobre 2009 12:04 12
84 Dveloppez des applications pour liPhone
doigt de lutilisateur. Elle montre lintrt des informations enregistres prcdemment
dans les fonctions gestionnaires de gestes et dans prepareDrag.
Puisque le glisser-dposer se fond sur une transformation, lors dun glissement, toute rota-
tion et tout redimensionnement dj effectus doivent tre appliqus en plus du dplace-
ment. En effet, le webkitTransform du style est rinitialis chacune de ses utilisations.
Si les informations de rotation et de redimensionnement ntaient pas incluses dans la
chane de transformation, llment serait considr dans sa taille et son orientation
dorigine lors du glissement.
Une chane de transformation qui provoque un dplacement, une rotation et un redimen-
sionnement contient plusieurs fonctions et prend laspect suivant :
"translate(-1px, 5px) rotateZ(21deg) scale(0.9)"
Cette instruction dplace llment de un pixel vers la gauche et de cinq pixels vers le bas.
Puis elle pivote llment autour de son axe Z. Enn, la taille de llment est xe 90 %
de sa taille dorigine.
Lordre des fonctions est important. Si la rotation se trouve gauche du dplacement dans
la chane, elle se produit avant celui-ci. Par consquent, le dplacement se fait selon un
angle avec les axes X et Y au lieu de se faire le long de ces axes. Le glisser-dposer aurait
un comportement trange, car llment se dplacerait en dcalage du mouvement du
doigt de lutilisateur au lieu de le suivre.
Le code de cration de la chane se trouve aux lignes 13 25. Elles concatnent une sous-
chane une chane qui contient la dclaration de la fonction translate.
1 function dragIt(event){
2 stopDefault(event);
3
4 this.x = event.targetTouches[0].clientX - this.offsetX;
5 this.y = event.targetTouches[0].clientY - this.offsetY;
6
7 if(this.lastX || this.lastY){
8 this.x += this.lastX;
9 this.y += this.lastY;
10 }
11 this.style.webkitTransformOriginX = 50%;
12 this.style.webkitTransformOriginY = 50%;
13 var modStringFragment = ;
14 if(this.isChangeable){
15 if(this.rotation){
16 modStringFragment +=
17 rotateZ(+this.oldRotation+deg);
18 }
iPhone Livre Page 84 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 85
19 if(this.oldScale){
20 modStringFragment +=
21 scale(+this.oldScale+);
22 }
23 }
24 var modString = translate( + this.x + px,
25 + this.y + px)+modStringFragment;
26
27 this.style.webkitTransform = modString;
28 if(this.dragCmd){
29 var params = new Array();
30 params.push(event);
31 params.push(this);
32 handleRequest(this.dragCmd, params);
33 }
34 }
Les lignes 11 et 12 prsentent un certain intrt. Les attributs webkitTransformOriginX
et webkitTransformOriginY sont xs leur valeur par dfaut. Comme vous le verrez
plus loin dans cette section, cette opration doit tre effectue dans le cas de tout redimen-
sionnement ou rotation. Sinon, si lutilisateur fait glisser un lment, celui-ci saute et le
doigt ne se trouve pas sur le point de llment touch initialement par lutilisateur.
Lorsque lutilisateur retire son doigt de lcran de lappareil, un vnement ontouchend
est dclench et la fonction gestionnaire dragDone est invoque. Le code suivant, extrait
du chier QCUtilities.js, montre que son rle est de rinitialiser certains attributs de
llment leur valeur dorigine et denregistrer des informations en vue de leur utilisation
ultrieure.
function dragDone(event){
this.dragging = false;
this.ontouchmove = null;
this.ontouchend = null;
this.lastX = this.x;
this.lastY = this.y;
this.style.zIndex = this.oldZIndex;
if(this.dropCmd){
var params = new Array();
params.push(event);
params.push(this);
handleRequest(this.dropCmd, params);
}
}
iPhone Livre Page 85 Vendredi, 30. octobre 2009 12:04 12
86 Dveloppez des applications pour liPhone
Dans cette fonction, les gestionnaires ontouchmove et ontouchend sont retirs an
dviter les interfrences avec le traitement du geste. Les coordonnes x et y actuelles de
lvnement sont enregistres et une commande est excute si lune delles est posi-
tionne.
Aprs avoir vu lensemble des mthodes sophistiques du glisser-dposer, le traitement
des gestes est plus facile comprendre. Tout comme la prise en charge des gestes peut
affecter le code du glisser-dposer, la gestion du glisser-dposer peut affecter le code de
redimensionnement et de rotation.
La fonction prepareGesture, dont le code donn ci-aprs se trouve dans le chier QCUti-
lities.js, est plus simple que la fonction prepareDrag. Elle xe quelques attributs, mais
elle na pas besoin de retarder certaines oprations, comme nous lavons expliqu prc-
demment dans cette section.
function prepareGesture(event){
stopDefault(event);
this.changing = true;
this.oldZIndex = this.style.zIndex;
this.style.zIndex = 50;
if(this.startChangeCmd){
var params = new Array();
params.push(event);
params.push(this);
handleRequest(this.startChangeCmd, params);
}
}
linstar des autres fonctions de prise en charge des vnements de geste, celle-ci
demande au framework dexcuter une commande en invoquant la fonction handleRequest.
Vous pouvez excuter autant de fonctions diffres que vous souhaitez aprs la termi-
naison du gestionnaire dvnements de geste. Pour de plus amples informations concernant
lassociation de commandes des fonctions, consultez le Chapitre 2.
Lorsque lutilisateur dplace son doigt sur lcran, un vnement ongesturechange est
dclench de manire rpte. Cela conduit linvocation de la fonction changeIt, dont le
code extrait du chier QCUtilities.js est donn ci-aprs. Cette fonction est responsable du
redimensionnement et de la rotation de llment en fonction de linteraction de lutilisateur
avec lappareil.
Notez quil est possible deffectuer un geste du doigt sur deux lments diffrents ou plus.
En gnral, cela vient dune erreur de lutilisateur et, par consquent, le code doit viter
que les lments ne ragissent lorsquils sont touchs (lignes 5 8).
iPhone Livre Page 86 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 87
Il est galement possible que lutilisateur effectue un pincement qui produit un lment
trop petit pour accepter deux doigts. Si ce comportement tait autoris, lutilisateur ne
pourrait plus redimensionner llment, qui ne serait donc pas modiable. Les lignes 14
19 vitent que lutilisateur ne rduise trop un lment.
Nous lavons expliqu prcdemment, lordre des dclarations des fonctions dans la
chane de transformation est important. Pour que la rotation et le redimensionnement dun
lment russissent, le dplacement doit se produire en dernier, en le dclarant la n de
la chane.
"rotateZ(21deg) scale(0.9) translate(-1px, 5px)"
Si le dplacement avait lieu en premier alors que lutilisateur tente de faire pivoter un
lment, celui-ci se dplacerait progressivement au cours de la rotation. Si le dplacement
ntait pas inclus, llment pivoterait autour de son coin suprieur gauche dorigine,
comme dni dans la classe CSS associe. Ces deux comportements ne sont pas acceptables.
1 function changeIt(event){
2 stopDefault(event);
3 // Lutilisateur peut avoir pos un seul doigt
4 // lintrieur de la cible.
5 if(this.dragging
6 || (this.touches && this.touches.length < 2)){
7 return;
8 }
9
10 this.rotation = event.rotation;
11 var rotationValue = this.rotation + this.oldRotation;
12 var scaleValue = event.scale * this.oldScale;
13 // Faire en sorte que llment ne soit pas trop petit pour accepter deux
touchers.
14 if(this.offsetWidth * scaleValue < 150){
15 scaleValue = 150/this.offsetWidth;
16 }
17 else if(this.offsetHeight * scaleValue < 150){
18 scaleValue = 150/this.offsetHeight;
19 }
20 this.scale = scaleValue;
21
22 var modString = rotateZ(+rotationValue+
23 deg) scale(+scaleValue+);
24 if(this.lastX || this.lastY){
25 modString += translate( + this.lastX + px,
26 + this.lastY + px);
iPhone Livre Page 87 Vendredi, 30. octobre 2009 12:04 12
88 Dveloppez des applications pour liPhone
27 // Actualiser le centre de rotation.
28 this.xCenterOffset = 50
29 + (this.lastX/this.offsetWidth)
30 * 100;
31 this.yCenterOffset = 50
32 + (this.lastY/this.offsetHeight)
33 * 100;
34
35 this.style.webkitTransformOriginX =
36 (this.xCenterOffset)+%;
37 this.style.webkitTransformOriginY =
38 this.yCenterOffset)+%;
39 }
40 this.style.webkitTransform = modString;
41
42 if(this.changeCmd){
43 var params = new Array();
44 params.push(event);
45 params.push(this);
46 handleRequest(this.changeCmd, params);
47 }
48 }
Les lignes 22 39 crent la chane de transformation et xent les valeurs de webkit-
TransformOrigin pour que le redimensionnement et la rotation puissent se produire par
rapport au centre visuel de llment modi. Les changements dorigine effectus dans le
code prcdent expliquent les rinitialisations ralises dans la mthode dragIt dcrite
prcdemment. Lorigine de la transformation est xe au milieu de llment, conformment
son dcalage courant par rapport sa position initiale.
Lorsque lutilisateur retire ses doigts de lcran, un vnement ongestureend est dclen-
ch et le gestionnaire gestureDone est invoqu. Il est comparable la mthode dragDone,
une exception prs : comme la fonction prepareDrag, il utilise une minuterie.
1 function gestureDone(event){
2 this.style.zIndex = this.oldZIndex;
3 // Lutilisateur na peut-tre pas effectu une rotation.
4 // Dans ce cas, rotation nest pas dfini.
5 if(this.rotation){
6 this.oldRotation += this.rotation;
7 }
8 // Lutilisateur na peut-tre pas effectu un pincement.
9 // Dans ce cas, scale nest pas dfini.
10 if(this.scale){
11 this.oldScale = this.scale;
12 }
iPhone Livre Page 88 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 3 Interfaces utilisateur 89
13
14 if(this.doneChangeCmd){
15 var params = new Array();
16 params.push(event);
17 params.push(this);
18 handleRequest(this.doneChangeCmd, params);
19 }
20 var self = this;
21 this.timeOut = setTimeout(function(){
22 self.changing = false;
23 },75);
24 }
Cette minuterie (lignes 21 23) existe pour des raisons semblables celles donnes pour
prepareDrag. Lorsque lvnement ongestureend est dclench, certains vnements de
toucher ne doivent pas tre traits. Si lattribut changing de llment est immdiatement
x false (ligne 22), alors, daprs le code de prepareDrag vu prcdemment, les
gestionnaires du glissement sont activs.
Si ces gestionnaires du glissement sont activs pour un geste de redimensionnement ou de
rotation, llment saute de manire erratique sur lcran et lexprience de lutilisateur en
est affecte ngativement.
Bien que les comportements de glisser-dposer, de redimensionnement et de rotation doivent
connatre lexistence des uns et des autres, ils doivent tre strictement spars. Dans le cas
contraire, un comportement confus et alatoire de lapplication est possible. Avec le code
prsent dans cette section, extrait du chier QCUtilities.js, vous disposez dune mise en uvre
cl en main des fonctionnalits de glisser-dposer, de redimensionnement et de rotation.
En rsum
Du point de vue de lutilisateur, linterface de lapplication constitue votre application.
Une mauvaise conception de linterface utilisateur, comme dans le cas du jeu DollarStash,
risque de couler votre application avant que vous ayez lopportunit de lamliorer ou de
la corriger. Nous lavons expliqu dans ce chapitre, une conception avise de linterface
tire parti des trois principes de base suivants :
Ne pas surprendre lutilisateur. Les interactions doivent dclencher les comportements
attendus.
Rendre linterface intuitive. Lutilisateur ne doit pas avoir besoin de lire une documen-
tation pour utiliser lapplication.
Ne pas demander aux appareils plus quils ne peuvent raliser. Les ressources processeur
et mmoire tant limites, elles doivent tre utilises de manire approprie.
iPhone Livre Page 89 Vendredi, 30. octobre 2009 12:04 12
90 Dveloppez des applications pour liPhone
Si vous respectez ces rgles de base et le HIG dApple, votre application aura des chances
de succs beaucoup plus leves. Bien que ces rgles puissent sembler strictes, elles laissent
le champ libre la crativit, comme la montr le module de glisser-dposer, de redimen-
sionnement et de rotation.
Ce module, sil est cr et employ intelligemment, permet damliorer normment
lexprience de lutilisateur avec votre application. En effet, il se fonde sur les possibilits
multitouch de liPhone et de liPod Touch, ainsi que sur le HIG dApple.
iPhone Livre Page 90 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
4
GPS, acclromtre et
autres fonctions natives
avec QuickConnectiPhone
LiPhone propose des fonctionnalits uniques que vous pouvez exploiter dans vos applica-
tions. Il est notamment possible de faire vibrer le tlphone, de jouer des sons systme,
daccder aux donnes de lacclromtre et de consulter les informations de localisation
GPS. Durant le dveloppement de lapplication, vous pouvez galement crire des messa-
ges de dbogage sur la console Xcode. Ces fonctionnalits ne sont pas rserves aux appli-
cations crites en Objective-C. Les applications hybrides peuvent les utiliser depuis du
code JavaScript. La premire section de ce chapitre explique comment employer les fonc-
tionnalits natives de liPhone avec lAPI JavaScript de QuickConnect. La deuxime
prsente le code Objective-C qui sous-tend la bibliothque JavaScript QuickConnect.
iPhone Livre Page 91 Vendredi, 30. octobre 2009 12:04 12
92 Dveloppez des applications pour liPhone
Section 1 : activation de lappareil en JavaScript
LiPhone change la donne. Les dveloppeurs dapplications peuvent en effet accder ses
composants matriels, comme lacclromtre. Lexploitation des capacits natives de
liPhone permet de crer des applications innovantes. Leur comportement peut dpendre
des donnes de lacclromtre ou des informations de localisation GPS. Vous pouvez
dcider du moment o le tlphone vibre ou joue certains sons.
Le chier com.js de QuickConnectiPhone dnit une fonction qui permet daccder facile-
ment et simplement ces possibilits. Une application invoque makeCall pour envoyer
des requtes au tlphone. Son premier paramtre est une chane de commande, le second
contient les paramtres ncessaires lexcution de la commande, indiqus sous forme
dune chane de caractres. Le Tableau 4.1 recense chaque commande standard, les para-
mtres correspondants et le comportement obtenu.
Tableau 4.1 : Commandes reconnues par makeCall
Chane de commande Chane de message Comportement
logMessage Les informations afcher sur
la console Xcode.
Le message apparat sur la console Xcode
lexcution du code.
rec Une chane JSON qui repr-
sente un tableau JavaScript dont
le premier lment indique le
nom du chier audio crer. Le
second lment est start ou
stop selon que vous souhaitez
dmarrer ou arrter lenregis-
trement des donnes audio.
Un chier audio caf, dont le nom est dni par la
chane de message, est cr.
play Une chane JSON qui repr-
sente un tableau JavaScript dont
le premier lment indique le
nom du chier audio lire.
Le second lment est start
ou stop selon que vous sou-
haitez dmarrer ou arrter la
lecture du chier audio.
Le chier audio caf, sil existe, est jou au tra-
vers des haut-parleurs de lappareil ou des cou-
teurs.
loc Aucune. Le comportement Core Location de lappareil
est dclench et les informations de latitude, de
longitude et daltitude sont retournes lappli-
cation JavaScript.
playSound 1 Le tlphone vibre.
iPhone Livre Page 92 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 93
Lapplication DeviceCatalog comprend un bouton Vibrate qui, lorsque lutilisateur clique
dessus, fait vibrer le tlphone. Le gestionnaire dvnements onclick de ce bouton
est la fonction vibrateDevice prsente ci-aprs. Elle appelle makeCall en lui passant
la commande playSound avec le paramtre 1, ce qui dclenche le vibreur du tl-
phone. La commande playSound est utilise car liPhone traite les vibrations et les sons
systme brefs comme des sons.
function vibrateDevice(event)
{
// Le paramtre -1 dclenche le vibreur du tlphone.
makeCall("playSound", -1);
}
Puisque le vibreur et les sons systme sont traits de la mme manire, la lecture dun son
systme est quasiment identique au dclenchement du vibreur. Le gestionnaire dvne-
ments onclick du bouton Sound se nomme playSound. Vous le constatez dans le code
suivant, la seule diffrence entre cette fonction et la fonction vibrateDevice se trouve
dans le second paramtre.
function playSound(event)
{
// Le paramtre 0 demande au tlphone dmettre le son dun laser.
makeCall("playSound", 0);
}
Lorsque le second paramtre est 0, le chier laser.wav inclus dans les ressources du projet
DeviceCatalog est jou en tant que son systme. Les sons systme ne doivent pas durer
plus de 5 secondes et ne sont pas jous comme les autres sons "normaux". Les chiers
audio plus longs sont lus avec la commande play, que nous examinerons plus loin dans
cette section.
La fonction makeCall employe par les fonctions prcdentes est crite en JavaScript. Elle
est constitue de deux parties. La premire place le message dans une le dattente sil ne
peut pas tre envoy immdiatement. La seconde envoie le message au code Objective-C
playSound 0 Le chier audio laser est jou.
showDate DateTime. Le slecteur de date et dheure natif est afch.
showDate Date. Le slecteur de date natif est afch.
Tableau 4.1 : Commandes reconnues par makeCall (suite)
Chane de commande Chane de message Comportement
iPhone Livre Page 93 Vendredi, 30. octobre 2009 12:04 12
94 Dveloppez des applications pour liPhone
sous-jacent en vue de son traitement. Pour passer le message, une URL inexistante, call,
est affecte la proprit window.location, et les paramtres de la fonction sont prciss
dans lURL.
function makeCall(command, dataString)
{
var messageString = "cmd="+command+"&msg="+dataString;
if(storeMessage ||!canSend){
messages.push(messageString);
}
else{
storeMessage = true;
window.location = "call?"+messageString;
}
}
Avec ce type dURL, un message comprenant lURL et ses paramtres est envoy un
composant Objective-C du framework QuickConnectiPhone. Ce composant interrompt le
chargement de la nouvelle page et passe la commande et le message reus au code de
traitement fourni par le framework. La Section 2 dtaille ce fonctionnement.
Les commandes playSound, logMessage, rec et play sont unidirectionnelles. Autrement
dit, les communications se font depuis JavaScript vers Objective-C, sans que des donnes
ne soient retournes. Les autres commandes unidirectionnelles standard dclenchent la
transmission de donnes depuis les composants Objective-C vers le code JavaScript.
La transmission des donnes au code JavaScript peut se faire de deux manires. La
premire est employe pour passer les informations dacclration dans les coordonnes x,
y et z par un appel la fonction JavaScript handleRequest dcrite au Chapitre 2. Cet
appel utilise la commande accel et les coordonnes x, y et z passes sous forme dun
objet JavaScript depuis les composants Objective-C du framework.
Le chier mappings.js montre que la commande accel est associe la fonction
displayAccelerationVCF :
mapCommandToVCF(accel, displayAccelerationVCF);
Ainsi, displayAccelerationVCF est appele chaque fois que lacclromtre dtecte un
mouvement. Cette fonction est responsable du traitement de tous les vnements daccl-
ration. Dans lapplication DeviceCatalog, elle place simplement les valeurs x, y et z dans
un lment HTML <div>. Vous devez modier cette fonction pour exploiter ces valeurs
dans votre application.
La seconde manire de renvoyer des donnes au code JavaScript se fonde sur un appel la
fonction JavaScript handleJSONRequest. Elle fonctionne de manire semblable la fonction
iPhone Livre Page 94 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 95
handleRequest dcrite au Chapitre 2, mais elle attend une chane JSON en second para-
mtre. Cette fonction est une faade pour la fonction handleRequest. Le code suivant
montre quelle convertit simplement la chane JSON indique en un objet JavaScript, puis
passe la commande et le nouvel objet la mthode handleRequest. Cette manire de
transfrer des donnes est utilise pour la demande de localisation GPS initie par un
appel makeCall("loc") et la demande dafchage dun slecteur de date et dheure.
function handleJSONRequest(cmd, parametersString){
var paramsArray = null;
if(parametersString){
var paramsArray = JSON.parse(parametersString);
}
handleRequest(cmd, paramsArray);
}
Dans les deux cas, les donnes rsultantes sont converties en une chane JSON et passes
handleJSONRequest. Pour de plus amples informations concernant le format JSON,
consultez lAnnexe A.
Puisquil existe des bibliothques JSON pour JavaScript et Objective-C, ce format consti-
tue une bonne solution pour changer des informations complexes entre ces deux langages
dans une application. Il est par exemple employ par les gestionnaires onclick pour le
dmarrage et larrt de lenregistrement et de la lecture des chiers audio.
La fonction playRecording est caractristique des gestionnaires associs aux boutons de
linterface utilisateur qui activent les comportements de lappareil. Lexemple suivant
montre quelle cre un tableau JavaScript, ajoute deux valeurs, convertit le tableau en une
chane JSON et appelle la fonction makeCall avec la commande play.
function playRecording(event)
{
var params = new Array();
params[0] = "recordedFile.caf";
params[1] = "start";
makeCall("play", JSON.stringify(params));
}
Pour stopper la lecture, un appel makeCall avec la commande play est galement effec-
tu, mais le paramtre start est remplac par stop. La fonction terminatePlaying dnie
dans le chier main.js met en uvre cette procdure.
Le dmarrage et larrt de lenregistrement dun chier audio sont cods de manire
semblable playRecording et terminatePlaying, except que la commande play est
iPhone Livre Page 95 Vendredi, 30. octobre 2009 12:04 12
96 Dveloppez des applications pour liPhone
remplace par rec. Puisque le contrle de ces deux fonctionnalits connexes se fait de la
mme faon, il est plus facile dajouter ces comportements dans une application.
Nous lavons vu prcdemment dans cette section, certains comportements de lappareil,
comme le vibreur, ncessitent une communication depuis le code JavaScript vers les
composants Objective-C. Dautres, comme la lecture des coordonnes GPS ou des rsul-
tats dun slecteur, exigent une communication dans les deux directions. La Figure 4.1
prsente lapplication DeviceCatalog qui afche les informations GPS.
linstar des exemples unidirectionnels dj prsents, la communication dbute dans le
code JavaScript de lapplication. La fonction getGPSLocation dnie dans le chier
main.js initie la communication en appelant makeCall. Notez que dans les exemples
prcdents makeCall ne retourne aucune valeur. Elle utilise un protocole asynchrone pour
communiquer avec le ct Objective-C de la bibliothque, mme lorsque la communication
est bidirectionnelle.
function getGPSLocation(event)
{
document.getElementById(locDisplay).innerText = ;
makeCall("loc");
}
Figure 4.1
Lapplication
DeviceCatalog afche
les informations GPS.
iPhone Livre Page 96 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 97
Puisque la communication est asynchrone, comme dans le cas dAJAX, une fonction de
rappel doit tre cre et invoque pour recevoir les informations GPS. Dans le framework
QuickConnectiPhone, cette opration est ralise en associant la commande showLoc
une fonction :
mapCommandToVCF(showLoc, displayLocationVCF);
Dans cet exemple, elle est associe la fonction de contrle de lafchage nomme
displayLocationVCF, qui se contente dafcher la localisation GPS courante dans un
<div>. Bien videmment, les valeurs obtenues peuvent galement servir calculer des
distances, qui seront enregistres dans une base de donnes ou envoyes un serveur
laide de ServerAccessObject, dcrit au Chapitre 8.
function displayLocationVCF(data, paramArray){
document.getElementById(locDisplay).innerText = latitude:
+paramArray[0]+\nlongitude: +paramArray[1]+\naltitude:
+paramArray[2];
}
Lafchage dun slecteur, par exemple le slecteur de date et dheure standard, et la
prsentation de la slection se font de manire semblable lexemple prcdent. La proc-
dure dbute galement par un appel JavaScript au code de gestion de lappareil. Dans ce
cas, la fonction gestionnaire du bouton se nomme showDateSelector ; elle est dnie
dans le chier main.js.
function showDateSelector(event)
{
makeCall("showDate", "DateTime");
}
Comme pour les informations GPS, une association doit tre cre. Elle lie la commande
showPickResults la fonction de contrle de lafchage displayPickerSelection-
VCF :
mapCommandToVCF(showPickResults, displayPickerSelectionVCF);
La fonction associe la commande insre les rsultats de la slection effectue par lutili-
sateur dans un simple <div>. Bien videmment, les informations obtenues peuvent tre
employes de nombreuses autres manires.
function displayPickerSelectionVCF(data, paramArray){
document.getElementById(pickerResults).innerHTML = paramArray[0];
}
iPhone Livre Page 97 Vendredi, 30. octobre 2009 12:04 12
98 Dveloppez des applications pour liPhone
Certaines utilisations de makeCall, notamment dans les premiers exemples de cette
section, mettent en place une communication unidirectionnelle entre le code JavaScript et
les composants Objective-C. Celles que nous venons de prsenter emploient une commu-
nication bidirectionnelle. Il existe toutefois un autre type de communication unidirection-
nelle : de lappareil vers le code JavaScript. Lutilisation des informations de lacclromtre
en est un exemple.
Le gestionnaire Objective-C pour les vnements dacclration (voir Section 2) effectue
directement un appel la fonction JavaScript handleRequest en passant la commande
accel. Cette commande est associe la fonction de contrle de lafchage display-
AccelerationVCF :
mapCommandToVCF(accel, displayAccelerationVCF);
linstar des autres VCF, elle place les valeurs dacclration dans un <div>.
function displayAccelerationVCF(data, param){
document.getElementById(accelDisplay).innerText =x:
+param.x+\ny: +param.y+\nz: +param.z;
}
la diffrence des autres fonctions, elle reoit dans son paramtre param non pas un
tableau mais un objet. La Section 2 montre comment cet objet est cr partir des infor-
mations venant du gestionnaire Objective-C des vnements dacclration.
Cette section a expliqu comment ajouter aux applications JavaScript les fonctionnalits
de liPhone les plus demandes. La Section 2 dcrit les parties Objective-C du framework
qui le permettent.
Section 2 : activation de lappareil en Objective-C
Cette section suppose que vous matrisiez Objective-C et que vous sachiez comment
lutiliser pour crer des applications pour liPhone. Si ce nest pas le cas, lisez louvrage
The iPhone Developers Cookbook, dErica Sadun. Si vous souhaitez uniquement utiliser
le framework QuickConnectiPhone pour dvelopper des applications JavaScript pour
liPhone, vous ntes pas oblig de lire cette section.
Faire vibrer liPhone avec du code Objective-C est lun des comportements les plus
simples raliser. Si vous incluez le framework AudioToolbox dans les ressources du
projet, la ligne suivante suft :
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
iPhone Livre Page 98 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 99
La question qui se pose alors est : "Comment puis-je faire en sorte que la fonction Audio-
ServicesPlaySystemSound soit appele lorsque le code modie lattribut location de
UIWebView ?"
La classe QuickConnectViewController implmente la mthode dlgue should-
StartLoadWithRequest. Puisque QuickConnectViewController est le dlgu du
UIWebView embarqu, nomm aWebView, cette mthode est invoque chaque fois que le
UIWebView embarqu voit son attribut location modi. Le code suivant, ainsi que la
ligne 90 du chier QuickConnectViewController.m, montre laffectation de ce dlgu :
[aWebView setDelegate:self];
Le comportement de base de la fonction shouldStartLoadWithRequest est simple. Sa
conception vous permet de dcider si la nouvelle page demande doit tre rellement char-
ge. Le framework se fonde sur cette facult pour interdire le chargement de la page lors
des requtes effectues par les appels JavaScript dcrits la Section 1 et pour excuter un
autre code Objective-C.
La mthode shouldStartLoadWithRequest prend plusieurs paramtres :
curWebView. Le UIWebView qui contient lapplication JavaScript.
request. Un NSURLRequest qui contient, entre autres, la nouvelle URL.
navigationType. Un UIWebViewNavigationType qui peut tre utilis pour dtermi-
ner si la requte est le rsultat dun clic sur un lien ou si elle a t gnre suite une
autre action.
-(BOOL)webView:(UIWebView *)curWebView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
LURL compose par la fonction JavaScript makeCall pour faire vibrer le tlphone,
call?cmd=playSound&msg=-1, est contenue dans lobjet request et peut tre facilement
retrouve sous forme dune chane de caractres en envoyant le message URL cet objet.
Ce message retourne un objet de type NSURL, auquel est ensuite pass le message absolute-
String. Nous obtenons ainsi un pointeur NSString qui reprsente lURL. Cette chane,
enregistre dans la variable url, peut tre dcompose dans un tableau, en utilisant le
point dinterrogation (?) comme caractre de sparation. Le tableau rsultant contient des
pointeurs NSString.
NSString *url = [[request URL] absoluteString];
NSArray *urlArray = [url componentsSeparatedByString:@"?"];
iPhone Livre Page 99 Vendredi, 30. octobre 2009 12:04 12
100 Dveloppez des applications pour liPhone
urlArray contient deux lments. Le premier correspond la partie call de lURL,
tandis que le second est la chane de commande cmd=playSound&msg=-1. Pour dterminer
la commande et ses paramtres, dans ce cas 1, nous devons poursuivre lanalyse de la
chane de commande. Pour cela, commandString est dcompose en fonction du caractre
& dans le tableau nomm urlParamsArray.
NSString *commandString = [urlArray objectAtIndex:1];
NSArray *urlParamsArray = [commandString componentsSeparatedByString:@"&"];
// La commande est le premier paramtre dans lURL.
cmd = [[[urlParamsArray objectAtIndex:0]
componentsSeparatedByString:@"="] objectAtIndex:1];
Dans notre exemple, demander au tlphone de vibrer, le premier lment du tableau
urlParamsArray est cmd=playSound et le second est msg=-1. Ainsi, en dcoupant les
lments de urlParamsArray avec le caractre = comme dlimiteur, nous pouvons obtenir
la commande excuter et son paramtre.
Les lignes 1 3 du code suivant enregistrent le paramtre pass dans lURL en tant que
valeur associe la cl msg dans la variable parameterArrayString de type NSString.
Puisque le code JavaScript qui a compos lURL convertit toutes ses composantes au
format JSON, ce NSString est un objet qui a t converti dans ce format. Cela inclut des
nombres, comme dans notre exemple, des chanes de caractres, des tableaux et dautres
paramtres passs depuis JavaScript. Par ailleurs, si des espaces ou dautres caractres
spciaux apparaissent dans les donnes, UIWebView leur applique lchappement dans
lURL. Cest pourquoi les lignes 6 8 suppriment lchappement sur ces caractres
spciaux dans la chane JSON.
1 NSString *parameterArrayString = [[[urlParamsArray
2 objectAtIndex:1] componentsSeparatedByString:@"="]
3 objectAtIndex:1];
4 // Retirer tout encodage ajout, comme lchappement des caractres
5 // effectu dans lURL par UIWebView.
6 parameterArrayString = [parameterArrayString
7 stringByReplacingPercentEscapesUsingEncoding:
8 NSASCIIStringEncoding];
9 SBJSON *generator = [SBJSON alloc];
10 NSError *error;
11 paramsToPass = [[NSMutableArray alloc]
12 initWithArray:[generator
13 objectWithString:parameterArrayString
14 error:&error]];
iPhone Livre Page 100 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 101
15 if([paramsToPass count] == 0){
16 // Si aucun tableau de donnes nest envoy, une chane a d tre passe
17 // comme seul paramtre.
18 [paramsToPass addObject:parameterArrayString];
19 }
20 [generator release];
Les lignes 9 14 convertissent la chane JSON parameterArrayString en un objet
Objective-C NSArray natif. La ligne 9 instancie un objet generator de type SBJSON,
auquel le message objectWithString est ensuite envoy :
- (id)objectWithString:(NSString*)jsonrep error:(NSError**)error;
Ce message en plusieurs parties comprend une chane JSON, dans ce cas parameter-
ArrayString, et un pointeur error de type NSError. Lorsquune erreur se produit au
cours du processus de conversion, le pointeur error est affect, sinon il vaut nil.
Dans ce cas, la valeur de retour de ce message est 1. Si un tableau JavaScript est converti
en chane, la valeur de retour est un pointeur NSArray, ou, dans le cas dune chane Java-
Script, il sagit dun pointeur NSString. Lorsquun objet JavaScript de type personnalis
est pass, lobjet retourn est un pointeur NSDictionary.
ce stade, puisque nous disposons de la commande et de ses paramtres, il est possible
dutiliser une instruction if ou case pour effectuer lopration demande. Toutefois, ces
instructions conditionnelles ne constituent pas la solution optimale car elles doivent tre
modies chaque fois quune commande est ajoute ou retire. Au Chapitre 2, un
problme comparable a t rsolu dans la partie JavaScript de QuickConnectiPhone en
mettant en place une fonction contrleur frontal, nomme handleRequest, qui contient
des appels aux implmentations des contrleurs dapplication. Puisque le problme est
identique ici, une version Objective-C de handleRequest doit permettre de le rsoudre.
La Section 3 sintresse la mise en uvre des contrleurs frontaux et des contrleurs
dapplication en Objective-C. La ligne de code suivante obtient une instance de lobjet
QuickConnect et lui passe le message handleRequest withParameters. Aucune autre
opration nest ncessaire dans la mthode dlgue shouldStartLoadWithRequest.
[[QuickConnect getInstance] handleRequest:cmd withParameters:paramsToPass];
Puisque nous utilisons le message handleRequest des objets QuickConnect, nous avons
besoin dun mcanisme pour lier les commandes la fonctionnalit requise, la manire
du Chapitre 2 en JavaScript. Lobjet QCCommandMappings, dclar dans les chiers
QCCommandMappings.m et .h du groupe QCObjC, contient toutes les associations pour les
objets de contrle mtier (BCO, Business Control Object) et les objets de contrle de
lafchage (VCO, View Control Object) de cet exemple.
iPhone Livre Page 101 Vendredi, 30. octobre 2009 12:04 12
102 Dveloppez des applications pour liPhone
Le code suivant correspond la mthode mapCommands de lobjet QCCommandMappings
qui est invoque au dmarrage de lapplication. Elle reoit limplmentation dun contr-
leur dapplication, qui cre les associations entre les commandes et les fonctionnalits. La
Section 3 expliquera le code du message mapCommandToVCO et de lappel mapCommands.
1 + (void) mapCommands:(QCAppController*)aController{
2 [aController mapCommandToVCO:@"logMessage" withFunction:@"LoggingVCO"];
3 [aController mapCommandToVCO:@"playSound" withFunction:@"PlaySoundVCO"];
4 [aController mapCommandToBCO:@"loc" withFunction:@"LocationBCO"];
5 [aController mapCommandToVCO:@"sendloc" withFunction:@"LocationVCO"];
6 [aController mapCommandToVCO:@"showDate" withFunction:@"DatePickerVCO"];
7 [aController mapCommandToVCO:@"sendPickResults" withFunction:@"Pick-
ResultsVCO"];
8 [aController mapCommandToVCO:@"play" withFunction:@"PlayAudioVCO"];
9 [aController mapCommandToVCO:@"rec" withFunction:@"RecordAudioVCO"];
10 }
La ligne 3 du code prcdent est en rapport avec le dclenchement du vibreur. Nous
lavons vu prcdemment dans cette section, la commande reue depuis la partie Java-
Script de lapplication se nomme playSound. En passant cette commande en premier
paramtre du message mapCommandToVCO et PlaySoundVCO comme paramtre de la
seconde partie, withFunction, nous crons un lien qui conduit le contrleur dapplication
envoyer un message doCommand avec le paramtre 1 la classe PlaySoundVCO. Vous le
constatez, toutes les autres commandes de lexemple DeviceCatalog envoyes depuis
JavaScript sont associes dans cette fonction.
Le code de PlaySoundVCO laquelle la commande playSound est associe se trouve dans
les chiers PlaySoundVCO.m et PlaySoundVCO.h. La mthode doCommand prend en
charge tous les comportements de lobjet.
Pour jouer un son systme, un son prdni (seule la vibration est dnie au moment de
lcriture de ces lignes) doit tre utilis ou un son systme doit tre gnr partir dun
chier audio. La mthode doCommand de la classe PlaySoundVCO illustre ces deux fonc-
tionnements.
1 + (id) doCommand:(NSArray*) parameters{
2 SystemSoundID aSound =
3 [((NSNumber*)[parameters objectAtIndex:1]) intValue];
4 if(aSound == -1){
5 aSound = kSystemSoundID_Vibrate;
6 }
7 else{
8 NSString *soundFile =
9 [[NSBundle mainBundle] pathForResource:@"laser"
iPhone Livre Page 102 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 103
10 ofType:@"wav"];
11 NSURL *url = [NSURL fileURLWithPath:soundFile];
12 // Si la lecture du fichier audio est trop longue,
13 // nous recevons une erreur -1500.
14 OSStatus error = AudioServicesCreateSystemSoundID(
15 (CFURLRef) url, &aSound );
16 }
17 AudioServicesPlaySystemSound(aSound);
18 return nil;
19 }
Vous pouvez le voir la ligne 4 de lexemple prcdent, si le paramtre dindice 1 a la
valeur 1, la variable SystemSoundID aSound est xe la valeur prdnie
kSystemSoundID_Vibrate. Sinon un son systme est cr partir du chier laser.wav qui
se trouve dans le groupe Resources de lapplication et un identiant gnr pour ce
nouveau son est affect la variable aSound.
Dans tous les cas, la fonction C AudioServicesPlaySystemSound est appele, le son est
jou ou lappareil vibre. Si lappareil est un iPod Touch, les demandes de vibration sont
ignores. Dans une application relle qui dispose de plusieurs sons, il est facile dtendre
cette fonction en passant dautres nombres dsignant les sons jouer.
Puisque SystemSoundID est de type numrique, les sons systme doivent tre gnrs au
dbut de lapplication et leurs identiants doivent tre passs la partie JavaScript de
lapplication en vue dune utilisation ultrieure. Cela vite la charge ncessaire la cra-
tion du son systme chaque fois quil doit tre jou et, par consquent, lutilisateur ne
constate aucun retard dans la lecture du son.
Puisque nous connaissons prsent la procdure qui permet de passer des commandes
depuis JavaScript Objective-C et la manire de faire vibrer lappareil ou de jouer un son
bref, il est facile de comprendre le passage dune commande Objective-C et le retour des
rsultats la partie JavaScript de lapplication.
En raison de la similitude de ces communications, la dtection de la localisation GPS, trs
utilise dans les applications pour liPhone, nous servira dexemple. Elle se fonde sur les
possibilits de communication bidirectionnelle entre JavaScript et Objective-C apportes
par le framework QuickConnectiPhone.
linstar de la gestion des commandes envoyes depuis le framework JavaScript, nous
avons besoin dun mcanisme pour lier la commande loc et ainsi pouvoir obtenir les
donnes et la rponse renvoyes.
[aController mapCommandToBCO:@"loc" withFunction:@"LocationBCO"];
[aController mapCommandToVCO:@"sendloc" withFunction:@"LocationVCO"];
iPhone Livre Page 103 Vendredi, 30. octobre 2009 12:04 12
104 Dveloppez des applications pour liPhone
Dans ce cas, il existe deux associations : la premire avec un BCO, la seconde avec un
VCO. linstar des BCF et VCF vues au Chapitre 2, les BCO permettent dobtenir les
donnes, les VCO, de les afcher.
Puisque les BCO dune commande donne sont excuts par le framework QuickConnect-
iPhone avant tous les VCO, un message doCommand est tout dabord envoy la classe
LocationBCO de manire obtenir et retourner les donnes GPS. La mthode doCommand
suivante appartient la classe LocationBCO. Elle effectue les appels permettant lappareil
de dterminer sa localisation GPS.
+ (id) doCommand:(NSArray*) parameters{
QuickConnectViewController *controller =
(QuickConnectViewController*)[parameters objectAtIndex:0];
[[controller locationManager] startUpdatingLocation];
return nil;
}
Cette mthode sollicite le matriel de localisation GPS en obtenant le premier lment du
tableau pass en paramtre la mthode et en lui demandant dactiver le matriel. Le
framework xe toujours le premier paramtre QuickConnectViewController an que
les BCO ou les VCO associs aux commandes puissent sen servir en cas de besoin. Dans
tous les BCO et VCO Objective-C, les paramtres provenant de JavaScript dbutent
lindice 1.
Lobjet QuickConnectViewController comprend un attribut CLLocationManager, nomm
locationManager, qui est activ et dsactiv en fonction de lapplication. Il est important que
ce gestionnaire ne sexcute pas plus longtemps que ncessaire car il consomme beaucoup
dnergie de la batterie. Par consquent, le code prcdent active le dispositif de localisa-
tion en lui envoyant un message startUpdatingLocation chaque fois que les informations
sont demandes. Le dispositif est dsactiv ds que la localisation est dtermine.
Les objets CLLocationManager se comportent de manire asynchrone. Autrement dit,
lorsquune demande de localisation est effectue, une fonction de rappel prdnie est
invoque aprs leur obtention. Cette fonction prdnie permet daccder au gestionnaire
de localisation et deux localisations : une localisation prcdemment dtermine et la
localisation actuelle.
Le gestionnaire de localisation afne progressivement la localisation de lappareil. Au
cours de cette procdure, il appelle plusieurs fois didUpdateToLocation. Lexemple de
code suivant calcule le temps ncessaire dterminer la nouvelle localisation. La ligne 9
vrie sil est infrieur cinq secondes et, dans lafrmative, poursuit la localisation.
1 (void)locationManager:(CLLocationManager *)manager
2 didUpdateToLocation:(CLLocation *)newLocation
iPhone Livre Page 104 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 105
3 fromLocation:(CLLocation *)oldLocation
4 {
5 // Si lvnement est relativement rcent, dsactiver les actualisations
pour conomiser la batterie.
6 NSDate* eventDate = newLocation.timestamp;
7 NSTimeInterval howRecent =
8 [eventDate timeIntervalSinceNow];
9 if (abs(howRecent) < 5.0){
10 [manager stopUpdatingLocation];
11 NSMutableArray *paramsToPass =
12 [[NSMutableArray alloc] initWithCapacity:2];
13 [paramsToPass addObject:self];
14 [paramsToPass addObject:newLocation];
15 [[QuickConnect getInstance]
16 handleRequest:@"sendloc"
17 withParameters:paramsToPass];
18 }
19 // Sinon, ignorer lvnement et passer au suivant.
20 }
Aprs avoir termin la localisation, le code envoie un message la classe contrleur fron-
tal de QuickConnect en lui indiquant quelle doit traiter une requte sendloc avec Quick-
ConnectViewController, self et la nouvelle localisation passe en paramtre suppl-
mentaire.
La commande sendloc est associe au gestionnaire LocationVCO dont la mthode
doCommand est reproduite ci-aprs. Cette mthode obtient le UIWebView nomm webView
partir du QuickConnectViewController qui a demand initialement les informations
de localisation GPS. Ces informations sont ensuite places dans le NSArray nomm
passingArray.
Pour retourner les informations GPS lobjet webView, le NSArray qui les contient doit
tre converti en une chane JSON. La classe SBJSON, dj employe prcdemment pour
crer un tableau partir dune chane JSON, est prsent utilise pour crer un NSString
partir du NSArray (lignes 21 et 22).
1 + (id) doCommand:(NSArray*) parameters{
2 QuickConnectViewController *controller =
3 (QuickConnectViewController*)[parameters
4 objectAtIndex:0];
5 UIWebView *webView = [controller webView];
6 CLLocation *location = (CLLocation*)[parameters
7 objectAtIndex:1];
8
9 NSMutableArray *passingArray = [[NSMutableArray alloc]
iPhone Livre Page 105 Vendredi, 30. octobre 2009 12:04 12
106 Dveloppez des applications pour liPhone
10 initWithCapacity:3];
11 [passingArray addObject: [NSNumber numberWithDouble:
12 location.coordinate.latitude]];
13 [passingArray addObject: [NSNumber numberWithDouble:
14 location.coordinate.longitude]];
15 [passingArray addObject: [NSNumber numberWithFloat:
16 location.altitude]];
17
18 SBJSON *generator = [SBJSON alloc];
19
20 NSError *error;
21 NSString *paramsToPass = [generator
22 stringWithObject:passingArray error:&error];
23 [generator release];
24 NSString *jsString = [[NSString alloc]
25 initWithFormat:@"handleJSONRequest(showLoc, %@)",
26 paramsToPass];
27 [webView
28 stringByEvaluatingJavaScriptFromString:jsString];
29 return nil;
30 }
Aprs avoir converti les informations de localisation GPS en une chane JSON qui repr-
sente un tableau de nombre, un appel au moteur JavaScript est effectu depuis lobjet
webView. Pour cela, nous commenons par crer un NSString qui contient le code Java-
Script excuter. Dans cet exemple, il sagit de handleJSONRequest, avec showLoc pour
commande et les informations GPS au format JSON comme chane. Nous lavons vu la
Section 1, cette requte fait apparatre les donnes GPS dans un <div> de la page HTML
afche.
Ayant prsent tudi cet exemple, vous pouvez examiner DatePickerVCO et PickResults-
VCO dans lapplication DeviceCatalog et voir comment cette mme approche est employe
pour afcher les slecteurs de date et dheure standard disponibles en Objective-C. Mme
si des slecteurs prdnis sont disponibles en JavaScript dans UIWebView, ils ne sont pas
aussi jolis que ceux fournis par Objective-C. En utilisant les slecteurs standard et ceux
que vous pourriez dnir, lexprience de lutilisateur avec votre application hybride nen
sera que meilleure.
iPhone Livre Page 106 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 107
Section 3 : implmentation Objective-C
de larchitecture de QuickConnectiPhone
Le code prsent aux Sections 1 et 2 dpend normment de limplmentation en Objec-
tive-C de larchitecture explique au Chapitre 2. Cette section dcrit cette implmentation.
Pour une explication complte de chaque composant, consultez le Chapitre 2, qui sint-
resse limplmentation JavaScript.
linstar de limplmentation JavaScript, toutes les demandes de comportement applicatif
se font au travers dun contrleur frontal. Celui-ci est mis en uvre par la classe Quick-
Connect, dont le code source se trouve dans les chiers QuickConnect.m et QuickConnect.h.
Puisque les messages envoys QuickConnect peuvent provenir de diffrents endroits de
lapplication, cette classe est un singleton.
Les classes singletons sont crites de manire quune seule instance de la classe soit
alloue dans une application. Lorsquelles sont bien implmentes, il existe toujours un
moyen dobtenir un pointeur sur cet objet unique depuis nimporte quel point de lapplica-
tion. Avec lobjet singleton QuickConnect, cela se fait au travers de la mthode de classe
getInstance, qui retourne lunique instance de QuickConnect alloue lors de la premire
invocation de cette mthode.
Puisquil sagit dune mthode de classe, un message getInstance peut tre envoy la
classe sans instancier un objet QuickConnect. Son invocation retourne un pointeur sur
linstance de QuickConnect alloue. Le code suivant montre que cette opration est rali-
se en affectant une instance de la classe un pointeur QuickConnect dni de manire
statique.
+ (QuickConnect*)getInstance{
// Puisque cette ligne est dclare avec static,
// elle est excute une seule fois.
static QuickConnect *mySelfQC = nil;
@synchronized([QuickConnect class]) {
if (mySelfQC == nil) {
mySelfQC = [QuickConnect singleton];
[mySelfQC init];
}
}
return mySelfQC;
}
Le message singleton envoy avant init utilise le comportement dni dans la super-
classe FTSWAbstractSingleton de lobjet QuickConnect. Cette superclasse met en
iPhone Livre Page 107 Vendredi, 30. octobre 2009 12:04 12
108 Dveloppez des applications pour liPhone
uvre le comportement de singleton, comme rednir les mthodes new, clone et dautres
que le programmeur pourrait utiliser par erreur pour allouer une autre instance de Quick-
Connect. Cest pourquoi seule la mthode getInstance est en mesure de crer et dutiliser
un objet QuickConnect. linstar de tous les objets bien crits en Objective-C, aprs son
allocation, lobjet QuickConnect doit tre initialis.
Lallocation et linitiation de lobjet ont lieu uniquement si aucun objet QuickConnect na
t affect lattribut mySelfQC. Par ailleurs, en raison de la synchronisation du contrle
de lexistence de lobjet QuickConnect instanci, ces oprations sont sres vis--vis des
threads.
- (void) handleRequest: (NSString*) aCmd withParameters:(NSArray*) para-
meters est une autre mthode de la classe QuickConnect. De mme que la fonction
JavaScript handleRequest(aCmd, parameters) du Chapitre 2, elle reprsente le mca-
nisme permettant dexcuter dans votre application la fonctionnalit demande.
Une chane de commande et un tableau de paramtres sont passs la mthode. Dans
lexemple suivant, les lignes 3 9 montrent quune suite de messages est envoye au
contrleur dapplication. Les lignes 3 et 4 commencent par excuter les VCO associs la
commande. Si la commande et les paramtres passent avec succs la validation, les BCO
associs la commande sont excuts via un message dispatchToBCO. Ce message
retourne un NSMutableArray qui contient les donnes du tableau parameters dorigine,
auxquelles ont t ajoutes celles accumules au cours des invocations des BCO.
1 - (void) handleRequest: (NSString*) aCmd
2 withParameters:(NSArray*) parameters{
3 if([self->theAppController dispatchToValCO:aCmd
4 withParameters:parameters]!= nil){
5 NSMutableArray *newParameters =
6 [self->theAppController dispatchToBCO:aCmd
7 withParameters:parameters];
8 [self->theAppController dispatchToVCO:aCmd
9 withParameters:newParameters];
10 }
11 }
Lorsque lappel dispatchToBCO:withParameters est termin, un message dispatch-
ToVCO:withParameters est envoy. Les VCO associs la commande indique sont alors
excuts.
En utilisant la mthode handleRequest:withParameters pour toutes les demandes de
fonctionnalits, chaque requte passe par le processus en trois tapes suivant :
validation ;
iPhone Livre Page 108 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 109
excution des rgles mtier (BCO) ;
excution des modications de lafchage (VCO).
Comme dans limplmentation JavaScript, chaque mthode dispatchTo est une faade.
Dans ce cas, la mthode Objective-C sous-jacente est dispatchToCO:withParameters.
Cette mthode commence par obtenir tous les objets de commande associs la
commande default partir du paramtre aMap. Il contient des BCO, des VCO ou des
ValCO, selon la mthode faade invoque. Ces objets de commande par dfaut, sils exis-
tent, sont obtenus et utiliss pour toutes les commandes. Si vous souhaitez que certains
objets de commande soient employs avec toutes les commandes, il est inutile de les asso-
cier tous chaque commande individuelle. Il suft de les associer une fois la commande
default.
Pour utiliser les objets de commandes obtenus, un message doCommand doit leur tre
envoy. Les lignes 19 23 de lexemple suivant montre ce message obtenu comme un
slecteur et le passage du message performSelector. Cela dclenche lexcution du
message doCommand que vous avez implment dans votre QCCommandObject.
1 - (id) dispatchToCO: (NSString*)command withParameters:
2 (NSArray*)parameters andMap:(NSDictionary*)aMap{
3 // Crer un tableau modifiable qui contient tous
4 // les paramtres existants.
5 NSMutableArray *resultArray;
6 if(parameters == nil){
7 resultArray = [[NSMutableArray alloc]
8 initWithCapacity:0];
9 }
10 else{
11 resultArray = [NSMutableArray
12 arrayWithArray:parameters];
13 }
14 // Affecter quelque chose result afin que
15 // lexcution se poursuive mme sil nexiste
16 // aucune association.
17 id result = @"Continue";
18 if([aMap objectForKey:@"default"]!= nil){
19 SEL aSelector = @selector(doCommand);
20 while((result = [((QCCommandObject*)
21 [aMap objectForKey:@"default"])
22 performSelector:aSelector
23 withObject:parameters])!= nil){
iPhone Livre Page 109 Vendredi, 30. octobre 2009 12:04 12
110 Dveloppez des applications pour liPhone
24 if(aMap == self->businessMap){
25 [resultArray addObject:result];
26 }
27 }
28 }
29 // Si tous les appels de mthode des objets de commande par dfaut
30 // retournent une valeur, excuter les objets personnaliss.
31 if(result!= nil && [aMap objectForKey:command]!=
32 nil){
33 NSArray *theCommandObjects =
34 [aMap objectForKey:command];
35 int numCommandObjects = [theCommandObjects count];
36 for(int i = 0; i < numCommandObjects; i++){
37 QCCommandObject *theCommand =
38 [theCommandObjects objectAtIndex:i];
39 result = [theCommand doCommand:parameters];
40 if(result == nil){
41 resultArray = nil;
42 break;
43 }
44 if(aMap == self->businessMap){
45 [resultArray addObject:result];
46 }
47 }
48 }
49 if(aMap == self->businessMap){
50 return resultArray;
51 }
52 return result;
53 }
Aprs lenvoi des messages doCommand tous les QCCommandObject associs la
commande default, la mme opration est effectue pour les QCCommandObject que vous
avez associs la commande passe en paramtre la mthode. Lexistence de ces QCCom-
mandObject se justie de la mme faon que les fonctions de contrle dans limplmenta-
tion JavaScript. Puisque les QCCommandObject contiennent le code du comportement de
lapplication, un exemple permettra de mieux comprendre leur cration.
Puisque QCCommandObject est la classe mre de LoggingVCO, celle-ci doit implmenter la
mthode doCommand. Lintgralit du contenu du chier LoggingVCO.m de lapplication
DeviceCatalog est donne ci-aprs. Sa mthode doCommand crit dans le journal de lappli-
cation en cours dexcution. Ce VCO journalise les messages de dbogage gnrs par le
code JavaScript de lapplication. La Figure 4.2 prsente les appels requis.
iPhone Livre Page 110 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 111
La mthode doCommand de la classe LoggingVCO est courte. Toutes les mthodes doCom-
mand des diffrents types dobjets de commande doivent toujours tre brves. Elles
doivent faire une seule chose et la faire bien. Si vous constatez que la mthode doCommand en
cours de dveloppement devient longue, vous devez envisager son dcoupage en composants
logiques et la cration de plusieurs classes dobjets de commande. En effet, lorsque ces
mthodes deviennent longues, il est probable quelles font plus dune chose.
Dans lexemple suivant, LoggingVCO soccupe uniquement de la journalisation des messa-
ges sur la console de dbogage de Xcode. Bien videmment, ce petit composant peut tre
rutilis avec de nombreuses commandes et dautres objets de commande.
Le comportement de ce VCO est mis en uvre par une seule ligne qui excute la fonction
NSLog. Le premier objet du tableau parameters est concatn une chane statique et afch.
#import "LoggingVCO.h"
@implementation LoggingVCO
+ (id) doCommand:(NSArray*) parameters{
NSLog(@"JavaScriptMessage: %@",
[parameters objectAtIndex:1]);
return nil;
}
@end
Pour que la journalisation soit effective, il faut une association entre la commande
logMessage et la classe LoggingVCO. Comme dans limplmentation JavaScript, cette
association se fait en ajoutant logMessage, en tant que cl, et le nom de la classe LoggingVCO,
Figure 4.2
Ce diagramme de squence montre les mthodes Objective-C invoques pour traiter une requte de jour-
nalisation dun message de dbogage JavaScript.
iPhone Livre Page 111 Vendredi, 30. octobre 2009 12:04 12
112 Dveloppez des applications pour liPhone
en tant que valeur, une mappe. Le code suivant, tir du chier QCCommandMappings.m
de lapplication DeviceCatalog, associe logMessage la classe LoggingVCO.
[aController mapCommandToVCO:@"logMessage" withFunction:@"LoggingVCO"];
Le contrleur dapplication reoit le message mapCommandToVCO:withFunction, dans
lequel le premier paramtre est la commande et le second, le nom du VCO. Cette mthode,
ainsi que dautres comme elle, utilise pour associer les types dobjets de commande, sont
des faades qui appellent la mthode mapCommandToCO sous-jacente.
La mthode mapCommandToCO permet dassocier plusieurs objets de commande une
seule commande en utilisant un NSMutableArray. Ce tableau contient les objets Class qui
correspondent aux noms de classe passs en second paramtre. Le code suivant prsente
limplmentation de la mthode mapCommandToCO.
- (void) mapCommandToCO:(NSString*)aCommand
withFunction:(NSString*)aClassName
toMap:(NSMutableDictionary*)aMap{
NSMutableArray *controlObjects =
[[aMap objectForKey:aCommand] retain];
if(controlObjects == nil){
NSMutableArray *tmpCntrlObjs =
[[NSMutableArray alloc] initWithCapacity:1];
[aMap setObject: tmpCntrlObjs forKey:aCommand];
controlObjects = tmpCntrlObjs;
[tmpCntrlObjs release];
}
// Obtenir la classe de lobjet de contrle
// pour le nom indiqu et ajouter un objet
// de ce type au tableau de la commande.
Class aClass = NSClassFromString(aClassName);
if(aClass!= nil){
[controlObjects addObject:aClass];
}
else{
MESSAGE(@"Erreur: classe %@ non trouve.
Vrifiez quelle existe sous ce nom et recommencez.");
}
}
Lajout des objets Class NSMutableArray permet dassocier nimporte quel nombre
dobjets de commande de mme type, VCO, BCO ou autres, la mme commande et de
les excuter ensuite individuellement dans lordre o les messages mapCommandTo* ont t
envoys. Ainsi, plusieurs VCO peuvent tre excuts squentiellement.
iPhone Livre Page 112 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 4 GPS, acclromtre et autres fonctions natives avec QuickConnectiPhone 113
Par exemple, un VCO peut afcher un UIView suivi dun autre qui modie lopacit dun
autre UIView, pour terminer par la journalisation dun message. Pour cela, il suft
denvoyer trois messages mapCommandToVCO avec la mme commande, mais avec trois
noms dobjets de commande diffrents.
Vous trouverez dautres exemples de BCO et de VCO dans lapplication DeviceCatalog.
Chacun est activ par des requtes effectues depuis la partie JavaScript de lapplication.
En rsum
Ce chapitre a montr comment activer plusieurs fonctionnalits trs demandes de
liPhone ou de liPod Touch depuis une application JavaScript. Lutilisation de la localisa-
tion GPS, des valeurs de lacclromtre, du vibreur du tlphone et du lecteur de sons ou
de chiers audio permet denrichir votre application.
En tudiant le code de lapplication DeviceCatalog et en connaissant Objective-C, vous
devez tre en mesure dajouter dautres fonctionnalits, comme le scan du rseau Bonjour
la recherche des appareils du voisinage, lajout, la suppression et lobtention des contacts
partir de lapplication Contacts, ou lexploitation dautres comportements intgrs
disponibles aux applications Objective-C.
En se fondant sur lapproche dcrite dans ce chapitre, votre application JavaScript a les
moyens de raliser quasiment tout ce quune application Objective-C peut effectuer. Le
Chapitre 6 en prsentera un exemple, qui consistera embarquer des cartes Google dans
une application en conservant laspect de lapplication de cartographie dApple.
iPhone Livre Page 113 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 114 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
5
GPS, acclromtre et
autres fonctions natives
avec PhoneGap
La bibliothque PhoneGap constitue une alternative au framework QuickConnect, qui a
fait lobjet du Chapitre 4. Bien quelle noffre pas toutes les possibilits de QuickConnect,
elle est souvent utilise pour accder aux informations de lappareil et ses fonctions. La
premire section de ce chapitre explique comment accder aux fonctionnalits natives de
liPhone en utilisant lAPI JavaScript de PhoneGap. La seconde prsente le code Java-
Script et Objective-C qui se cache derrire cette API.
Section 1 : activation de lappareil en JavaScript
Au moment de lcriture de ces lignes, le dveloppement de PhoneGap en est toujours
ses dbuts. Il gre donc un nombre limit de fonctionnalits natives. Cette section prsente
uniquement les comportements qui sont pris en charge du ct JavaScript et du ct
iPhone Livre Page 115 Vendredi, 30. octobre 2009 12:04 12
116 Dveloppez des applications pour liPhone
Objective-C de lapplication. Certaines parties du code de la bibliothque ne sont pas
encore termines ou pleinement oprationnelles. Les comportements correspondants ne
seront donc pas examins.
Le Tableau 5.1 recense les mthodes, les fonctions et les attributs qui font partie de lAPI
oprationnelle. Contrairement QuickConnectiPhone, elles ne se trouvent pas dans un
framework plus vaste et doivent donc tre invoques directement. Puisque les contrles
effectus par la version actuelle sont minimaux, vous devez vrier que les paramtres
passs aux fonctions sont valides et non null.
Nous lavons expliqu au Chapitre 4, QuickConnectiPhone inclut les chiers HTML, CSS
et JavaScript dans lapplication installe sur lappareil. Ce nest pas le cas de PhoneGap
1
.
la place, une application Objective-C gnrique de dmarrage, laquelle est donn le
nom de votre application, charge temporairement ces chiers partir dun serveur web sur
lequel vous les avez pralablement publis (voir Figure 5.1). Pour excuter votre applica-
tion, lappareil doit donc tre connect au rseau. Par consquent, vous ne devez pas
supposer que votre application fonctionnera correctement si lutilisateur se trouve dans un
avion o le rseau est inaccessible.
1. N.d.T. : rappelons qu partir de la version 0.7.3 PhoneGap enregistre les chiers JavaScript, HTML
et CSS sur lappareil, non plus sur un serveur web.
Figure 5.1
Avec PhoneGap, lobtention des chiers HTML, CSS et JavaScript dune application se fait
par un change requte-rponse.
Dmarrage dune application PhoneGap
URL
de requte
URL
de requte
Serveur web
Requte
HTML,
CSS
et JavaScript
HTML,
CSS
et JavaScript
Serveur web
Rponse
iPhone Livre Page 116 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 117
Lorsquune application PhoneGap dbute le chargement de ses composants web partir
du serveur, un appel est effectu depuis lapplication Objective-C gnrique vers le code
JavaScript. Cet appel xe les valeurs de plusieurs variables globales qui dcrivent lappa-
reil sur lequel lapplication sexcute. La mthode Device.init de lAPI JavaScript,
gnralement appele depuis une fonction dnie comme gestionnaire des vnements
onload, collecte les variables globales dnies par la partie Objective-C de lapplication et
les enregistre dans des attributs de lobjet Device de PhoneGap. Le code Objective-C qui
dnit ces variables sera prsent la Section 2.
init: function(model, version) {
...
Device.available = __gap;
Device.model = __gap_device_model;
Device.version = __gap_device_version;
Device.gapVersion = __gap_version;
Device.uuid = __gap_device_uniqueid;
...
}
Le code prcdent concerne les iPhone et iPod Touch. Chaque nom de variable globale
dbute par __ (deux souligns) et a une valeur unique. La variable __gap est utilise
comme indicateur qui prcise si le code JavaScript sexcute depuis une application
PhoneGap. Au moment de lcriture de ces lignes, cette variable est indispensable car les
fichiers HTML, CSS et JavaScript sont non pas inclus dans une application compile et
installe, mais tlchargs via Internet par lenveloppe PhoneGap. Si ces chiers de
lapplication sont chargs depuis un navigateur web la place dune application
PhoneGap, la variable __gap vaut null et peut tre utilise pour excuter du code
conditionnel.
La variable __gap_device_model contient une chane de caractres qui dcrit lappareil
sur lequel sexcute lapplication, comme iPhone, iPod Touch ou iPhone Simulator. Elle
inclut galement la version du systme dexploitation de lappareil, qui est enregistre
dans la variable globale __gap_device_version. Lidentiant global unique de lappareil
se trouve dans la variable __gap_device_uniqueid, tandis que la version de PhoneGap
est place dans __gap_version. Chacune de ces variables est disponible dans les attributs
publics de Device ou dans les variables globales. Le Tableau 5.1 dcrit chaque fonction
JavaScript qui vous permet daccder aux fonctionnalits de lappareil.
Lexemple PGDeviceCatalog comprend un bouton Vibrate qui, lorsque lutilisateur
clique dessus, fait vibrer le tlphone.
iPhone Livre Page 117 Vendredi, 30. octobre 2009 12:04 12
118 Dveloppez des applications pour liPhone
Tableau 5.1 : API JavaScript de PhoneGap
lment Paramtres Comportement
gotAcceleration() x la valeur de lacclration
selon laxe X.
y la valeur de lacclration
selon laxe Y.
z la valeur de lacclration
selon laxe Z.
Cette fonction nest pas prdnie. Pour obtenir
les informations de lacclromtre, vous devez
crer cette fonction quelque part dans votre appli-
cation. Le code Objective-C peut ensuite linvo-
quer en lui passant les valeurs en paramtres.
Device.init() Aucun. Collecte les informations concernant lappareil
partir des variables globales dnies au dmar-
rage de lapplication. Ces informations sont pla-
ces dans lobjet Device et incluent le type de
lappareil (iPhone/iPodTouch), la version de son
systme dexploitation, son identiant unique,
ainsi que la version de PhoneGap.
Device.vibrate() Aucun. Dclenche le vibreur du tlphone pendant la
dure standard.
Device.sound() clip une chane de caractres
qui prcise le nom et le type du
chier audio jouer, par exemple
"tweet.wav".
Le chier audio de nom indiqu doit se trouver
dans les ressources de lapplication ou une erreur
dexcution sera gnre.
Device.Loca-
tion.init()
Aucun. Dclenche lenvoi des informations de localisa-
tion dj prsentes dans la partie Objective-C au
code JavaScript en vue de leur traitement et/ou de
leur afchage.
Device.Loca-
tion.callback
Si une fonction de rappel est affecte cet attribut
de lobjet Location, elle est invoque lorsque les
informations GPS sont disponibles.
Device.Loca-
tion.wait()
func la fonction de rappel ex-
cute lorsque les informations
GPS sont disponibles.
Il sagit dune alternative la fonction
Device.Location.init().
Device.exec() command une chane de com-
mande passe la partie Objec-
tive-C de lapplication en vue de
son traitement, par exemple
"vibrate", "sound" ou "getLoc".
Cette fonction prend en charge toutes les commu-
nications avec la partie Objective-C de lapplica-
tion. Chaque commande envoye dclenche un
comportement natif diffrent de lappareil. Cette
mthode doit tre invoque depuis JavaScript si
vous crez un code Objective-C personnalis que
vous souhaitez excuter.
iPhone Livre Page 118 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 119
Le gestionnaire dvnements onclick du bouton est la fonction nomme vibrateDe-
vice. Elle appelle la mthode Device.vibrate qui dclenche le vibreur.
function vibrateDevice(event)
{
Device.vibrate();
}
La mthode Device.vibrate suivante est une faade pour la mthode exec de lobjet
Device. Elle invoque Device.exec en lui passant la commande vibrate. Toutes les
mthodes PhoneGap associes aux fonctionnalits de lappareil sont en ralit des faades
pour Device.exec.
vibrate: function() {
return Device.exec("vibrate")
}
La fonction Device.exec utilise dans le code prcdent est crite en JavaScript (voir ci-
aprs). linstar de QuickConnectiPhone, PhoneGap construit lURL et cre un message
compos de lURL et de la commande, comme vibrate, qui est envoy un composant
Objective-C faisant partie du framework PhoneGap sous-jacent. Ce composant arrte le
chargement de la nouvelle page et value les commandes envoyes. Pour de plus amples
informations concernant cette procdure, consultez la Section 2.
exec: function(command) {
if (Device.available) {
try {
document.location = "gap:" + command;
} catch(e) {
console.log("La commande " + command +
" na pas t excut en raison de lexception: " + e);
alert("Erreur dexcution de la commande " + command + ".")
}
}
}
Dans la partie catch du code prcdent, deux mcanismes sont utiliss pour indiquer un
problme lutilisateur. Le premier, un appel console.log, crit un message sur la
console de Dashcode. Il fonctionne uniquement lorsque lapplication sexcute dans Dash-
code, non sur lappareil.
Le second mcanisme se fonde sur une bote dalerte. Puisque PhoneGap a mis en uvre
les botes dalerte en Objective-C, cette solution fonctionne sur lappareil, mais, selon les
directives dApple, elle ne devrait jamais tre utilise dans les applications pour liPhone.
iPhone Livre Page 119 Vendredi, 30. octobre 2009 12:04 12
120 Dveloppez des applications pour liPhone
Pour de plus amples informations sur la conception de linterface utilisateur des applications
pour liPhone, consultez le Chapitre 3.
Les mthodes playSound et vibrate sont toutes deux unidirectionnelles, avec une
communication depuis JavaScript vers Objective-C, sans donnes retournes. La mthode
Device.Location.init est bidirectionnelle et des donnes fournies par la partie Objec-
tive-C de PhoneGap sont donc attendues. Comme le montre lexemple suivant, cette
mthode init est galement une faade pour la mthode Device.exec. Dans son cas, la
commande passe se nomme getloc.
init: function() {
...
Device.exec("getloc");
...
}
La Figure 5.2 illustre lexcution dune application PhoneGap qui a demand des informa-
tions de localisation GPS. Cette requte se fait galement au travers dune faade qui invoque
Device.exec.
Dans lapplication PGDeviceCatalog, la mthode Device.Location.init est appele
partir de la fonction getGPS constitue de quatre lignes. La troisime ligne invoque init
et signale la partie Objective-C que ses donnes GPS enregistres sont requises.
Figure 5.2
Lapplication PGDevice-
Catalog afche des infor-
mations concernant la
localisation GPS et
lappareil.
iPhone Livre Page 120 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 121
function getGPS(event){
Device.Location.callback = updateLocation;
Device.Location.init();
}
La deuxime ligne de getGPS informe lobjet Device.Location que la fonction update-
Location, dnie dans main.js, doit tre appele lorsque les donnes GPS ont t obte-
nues. Dans PhoneGap, ce processus est beaucoup plus rapide que dans
QuickConnectiPhone, car la bibliothque Objective-C de PhoneGap active le matriel
GPS de lappareil ds que lapplication est dmarre et le dsactive lorsquelle est quitte.
Lactivation du matriel GPS pendant tout le temps dexcution des applications Phone-
Gap, mme si les donnes ne sont pas employes, utilise une quantit importante dnergie
de la batterie. Cette consommation est tellement importante quApple prcise que laisser
le matriel GPS activ pendant la dure dexcution dune application revient tre "un
mauvais voisin". Avec cette approche, la batterie de lappareil risque de ne plus avoir suf-
samment de puissance pour les appels tlphoniques et lexcution dautres applications.
Cest pourquoi les applications PhoneGap doivent tre conues de manire sexcuter
pendant de courtes priodes de temps, mme si elles nexploitent pas les informations
GPS. Puisque QuickConnectiPhone dmarre le matriel GPS lorsque les informations de
localisation sont demandes et larrte ds quelles ont t obtenues, les applications dve-
loppes avec ce framework peuvent tre conues pour des dures dutilisation beaucoup
plus longues.
Pour obtenir les donnes de lacclromtre, une fonction nomme gotAcceleration(x, y,
z) doit tre implmente quelque part dans lapplication. Dans lexemple de PGDevice-
Catalog, elle se trouve dans le chier main.js.
function gotAcceleration(x, y, z){
document.getElementById(accelDisplay).innerHTML =
X: +x+<br/>Y: +y+ <br/>Z: +z;
}
Cette version de la fonction gotAcceleration afche uniquement les valeurs de laccl-
romtre. Dans votre implmentation, vous pouvez les utiliser de diffrentes manires, par
exemple comme un ltre passe-bas ou pour modier linterface utilisateur.
Puisque le simulateur de liPhone ne donne pas accs lacclromtre, vous devez excuter
lapplication sur un appareil rel pour voir lafchage de ces informations. Dans ce cas, la
fonction gotAcceleration est appele chaque fois que lacclromtre dtecte un
mouvement.
La bibliothque PhoneGap permet galement de jouer un chier audio depuis du code
JavaScript. La fonction playTweetSound constitue un exemple de cette fonctionnalit.
iPhone Livre Page 121 Vendredi, 30. octobre 2009 12:04 12
122 Dveloppez des applications pour liPhone
Elle appelle la mthode Device.playSound, qui, linstar de la mthode
Device.vibrate, est une faade pour Device.exec.
function playTweetSound(event) {
Device.playSound(bird.mp3);
}
La mthode playSound requiert en argument le nom complet du chier audio jouer. Ce
chier doit se trouver dans le groupe Resources du projet Xcode de lapplication. Il ne
peut pas tre plac sur le serveur web avec les chiers HTML, JavaScript et CSS. Sil nest
pas inclus aux ressources de lapplication, il nest pas lu.
Dans notre exemple, bird.mp3 est pass la mthode playSound de lobjet Device et il est
utilis en paramtre de la commande sound (voir ci-aprs). ce stade du dveloppement
de PhoneGap, playSound est la seule mthode oprationnelle qui gre une commande
avec des paramtres. Il semble que cela changera lorsque lquipe de dveloppements de
PhoneGap ajoutera dautres fonctionnalits. Pour de plus amples informations concernant
la feuille de route de PhoneGap, consultez lAnnexe C.
playSound: function(clip) {
return Device.exec(sound: + clip);
}
Cette section a montr comment activer les fonctionnalits natives de lappareil au travers
de PhoneGap. La Section 2 dcrit la partie Objective-C de la bibliothque PhoneGap qui
prend en charge cette possibilit.
Section 2 : activation de lappareil en Objective-C
Si vous ntes pas familier du langage Objective-C et de son utilisation dans le dveloppe-
ment dapplications pour liPhone, consultez le livre dErica Sadun, The iPhone Develo-
pers Cookbook. Si vous souhaitez simplement utiliser la bibliothque PhoneGap pour
crire des applications JavaScript pour liPhone, vous ntes pas oblig de lire cette
section.
Aprs que les chiers HTML, CSS et JavaScript de lapplication ont t obtenus partir
du serveur web, lAPI dclenche un vnement intercept et trait par la mthode
webViewDidStartLoad de lobjet GlassAppDelegate. Son rle est dinitialiser un objet
PhoneGap Device.
// Au chargement de lapplication web, lui passer
// les informations concernant lappareil.
iPhone Livre Page 122 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 123
- (void)webViewDidStartLoad:(UIWebView *)theWebView {
[theWebView stringByEvaluatingJavaScriptFromString:
[[Device alloc] init]];
}
La mthode init de lobjet Device cre une chane de caractres constitue dune suite
dappels JavaScript. Chacun de ces appels xe la valeur dune variable globale, notam-
ment le modle de lappareil, iPhone ou iPod Touch, son identiant unique et la version de
son systme dexploitation.
La chane cre est retourne par la mthode init an quelle puisse tre utilise par la
mthode stringByEvaluatingJavaScriptFromString de lobjet UIWebView. Lvalua-
tion de la chane par UIWebView permet de xer les valeurs de variables JavaScript globa-
les, comme __gap_device_uniqueid. Nous verrons plus loin dans ce chapitre comment
ces variables globales sont assembles dans un objet JavaScript.
@implementation Device
- (NSString *)init{
jsCallBack = nil;
myCurrentDevice = [UIDevice currentDevice];
return jsCallBack = [[NSString alloc] initWithFormat:@"\
__gap = true; \
__gap_version=0.1; \
__gap_device_model=%s; \
__gap_device_version=%s;\
__gap_device_uniqueid=%s;",
[[myCurrentDevice model] UTF8String],
[[myCurrentDevice systemVersion] UTF8String],
[[myCurrentDevice uniqueIdentifier] UTF8String]
];
}
- (void)dealloc {
[jsCallBack release];
[myCurrentDevice release];
[super dealloc];
}
@end
Ces variables globales sont xes sans effectuer une requte. Dautres fonctionnalits
vous obligent crire du code qui dclenche le comportement souhait.
iPhone Livre Page 123 Vendredi, 30. octobre 2009 12:04 12
124 Dveloppez des applications pour liPhone
Lun des comportements les plus faciles implmenter en Objective-C est lactivation du
vibreur de liPhone. Il suft en effet dune seule ligne de code lorsque le framework
AudioToolbox est inclus aux ressources du projet :
AudioServicesPlaySystemSound(kSystemSoundID_Vibrate);
Comment faire en sorte que la fonction AudioServicesPlaySystemSound soit appele
lorsque le code change lattribut location de UIWebView ?
La classe GlassAppDelegate implmente la mthode webView:shouldStartLoad-
WithRequest:navigationType. Puisque GlassAppDelegate est le dlgu du UIWeb-
View embarqu (voir ligne 36 du chier GlassAppDelegate.m), nomm aWebView, cette
mthode est invoque chaque fois que le UIWebView embarqu voit son attribut location
modi.
webView.delegate = self;
Le comportement de base de la fonction webView:shouldStartLoadWithRequest:navi-
gationType est simple. Sa conception vous permet dcrire du code qui dcide si la
nouvelle page demande doit tre rellement charge. La bibliothque PhoneGap se fonde
sur cette possibilit de dcision pour interdire les requtes de commande effectues par les
appels JavaScript dcrits la Section 1 et pour excuter un autre code Objective-C.
La mthode shouldStartLoadWithRequest prend plusieurs paramtres :
curWebView. Le UIWebView qui contient lapplication JavaScript.
request. Un NSURLRequest qui contient, entre autres, la nouvelle URL.
navigationType. Un UIWebViewNavigationType qui peut tre utilis pour dtermi-
ner si la requte est le rsultat dun clic sur un lien ou si elle a t gnre suite une
autre action.
-(BOOL)webView:(UIWebView *)curWebView
shouldStartLoadWithRequest:(NSURLRequest *)request
navigationType:(UIWebViewNavigationType)navigationType
LURL compose par la mthode JavaScript Device.exec pour faire vibrer le tlphone,
gap:vibrate, est contenue dans lobjet request et peut tre facilement retrouve sous
forme dune chane de caractres en envoyant le message URL cet objet. Ce message
retourne un objet de type NSURL, auquel est ensuite pass le message absoluteString.
Nous obtenons ainsi un pointeur NSString qui reprsente lURL.
NSString *url = [[request URL] absoluteString];
NSArray *urlArray = [url componentsSeparatedByString:@"?"];
iPhone Livre Page 124 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 125
Dans PhoneGap, on dtermine si lURL demande est relative celle de lapplication indi-
que dans le chier url.txt. Dans la ngative, le navigateur Safari est lanc pour afcher la
page dsigne par lURL. Dans ce cas, lapplication se termine, car liPhone nautorise
lexcution que dune seule application la fois.
Le code suivant obtient lhte demand, indiqu dans le paramtre url, et lhte de
lapplication indiqu dans appURL. Pour cela, le message host est envoy aux deux objets
NSURL.
Les lignes 3 et 4 envoient le message rangeOfString la variable urlHost. Cela qui-
vaut lappel de la mthode indexOf sur un objet JavaScript String. Le code suivant
dtermine si la valeur de lhte de lapplication est prsent dans lURL de requte.
1 NSString* urlHost = [url host];
2 NSString* appHost = [appURL host];
3 NSRange range = [urlHost rangeOfString:appHost
4 options:NSCaseInsensitiveSearch];
5 if (range.location == NSNotFound)
6 [[UIApplication sharedApplication] openURL:url];
7
8 NSString * jsCallBack = nil;
9 NSArray * parts = [urlString
10 componentsSeparatedByString:@":"];
La ligne 5 examine le rsultat de la mthode rangeOfString pour dterminer si appHost
a t trouv dans urlHost. Dans la ngative, le message openURL est envoy votre appli-
cation. Chaque fois que ce message openURL est envoy, votre application se termine et
lapplication approprie est dmarre. Si une URL commenant par map: est demande,
lapplication de cartographie de liPhone est lance avec lURL indique. Les autres types
possibles sont notamment http, qui lance Safari, tel, qui lance loutil de numrotation
tlphonique, mailto, qui lance lapplication de messagerie, et les URL youtube.com,
qui lancent lapplication YouTube. Dans tous les cas, votre application se termine.
Les lignes 9 et 10 dcomposent lURL de manire obtenir les composantes de la
commande et placent chacune delles dans un tableau nomm parts. Celui-ci est ensuite
valu pour dterminer la commande envoye et ses paramtres.
PhoneGap utilise une instruction conditionnelle if-then-else pour valuer le tableau
parts. Chaque commande active une condition diffrente. Dans la condition de la
commande vibrate, un objet Vibrate est instanci et le message vibrate lui est pass.
else if([(NSString *)[parts objectAtIndex:1]
isEqualToString:@"vibrate"]){
Vibrate *vibration = [[Vibrate alloc] init];
[vibration vibrate];
iPhone Livre Page 125 Vendredi, 30. octobre 2009 12:04 12
126 Dveloppez des applications pour liPhone
[vibration release];
NSLog(@"vibreur dclench");
}
Cest dans la mthode vibrate de lobjet Vibrate (chier Vibrate.m) que lappel Audio-
ServicesPlaySystemSound(kSystemSoundID_Vibrate); est effectu.
Le traitement des requtes concernant les informations GPS est diffrent. Cette commande
est gre directement au lieu dtre passe un objet qui la prendra en charge. Les lignes 5
7 crent une chane qui contient un appel JavaScript la fonction gotLocation(lat,
lon) dnie dans le chier phonegap.js, o lat et lon sont remplacs par la latitude et la
longitude courantes ; ces informations sont dtermines en permanence depuis le dmar-
rage de lapplication.
1 if([(NSString *)[parts objectAtIndex:1]
2 isEqualToString:@"getloc"]){
3 NSLog(@"location request!");
4
5 jsCallBack = [[NSString alloc]
6 initWithFormat:@"gotLocation(%f,%f);"
7 , lat, lon];
8 NSLog(@"callback: %@",jsCallBack);
9 [theWebView
10 stringByEvaluatingJavaScriptFromString:
11 jsCallBack];
12
13 [jsCallBack release];
14 }
Pour dclencher lexcution de la chane JavaScript jsCallBack, le message stringBy-
EvaluatingJavaScriptFromString, accompagn de la chane JavaScript en paramtre,
doit tre envoy lobjet UIWebView pass dans le paramtre theWebView la fonction
shouldStartLoadWithRequest. ce stade, la partie Objective-C de la bibliothque a
termin son travail.
La fonction JavaScript gotLocation appelle prsent la mthode set de lobjet
Device.Location :
function gotLocation(lat, lon) {
return Device.Location.set(lat, lon)
}
La mthode Device.Location.set enregistre la latitude et la longitude dans lobjet
Device.Location et appelle ensuite la fonction de rappel callback, si elle existe, comme
nous lavons expliqu la Section 1. Notez quaprs linvocation de la fonction de rappel
iPhone Livre Page 126 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 127
la ligne 6 xe lattribut callback null. Autrement dit, chaque fois que vous demandez
des informations de localisation, vous devez reprciser la mthode de rappel.
1 set: function(lat, lon) {
2 Device.Location.lat = lat;
3 Device.Location.lon = lon;
4 if(Device.Location.callback!= null) {
5 Device.Location.callback(lat, lon)
6 Device.Location.callback = null;
7 }
8 }
Si vous ne dnissez pas une mthode callback chaque fois que vous demandez des
informations de localisation, aucune fonction de rappel nest invoque.
Le traitement de la commande sound est comparable celui de la commande getloc.
Toutefois, puisque la partie JavaScript de lapplication nattend aucune donne, le
message stringByEvaluatingJavaScriptFromString nest pas envoy UIWebView.
la place, un objet Sound est cr comme dans le cas de la commande vibrate.
1 else if ([(NSString *)[parts objectAtIndex:1]
2 isEqualToString:@"sound"]) {
3 NSLog(@"playing sound");
4 NSLog([parts objectAtIndex:2]);
5 NSString *ef = (NSString *)[parts objectAtIndex:2];
6 NSArray *soundFile = [ef componentsSeparatedByString:@"."];
7
8 NSString *file = (NSString *)[soundFile objectAtIndex:0];
9 NSString *ext = (NSString *)[soundFile objectAtIndex:1];
10 NSLog(@"about to allocate %@, %@",file, ext);
11 sound = [[Sound alloc] initWithContentsOfFile:
12 [mainBundle pathForResource:file ofType:ext]];
13 NSLog(@"sound allocated");
14 [sound play];
15 }
Cet objet Sound, dni dans Sound.m, est initialis avec le chemin du chier audio. Nous
lavons indiqu la Section 1, ce chier doit rsider dans le groupe Resources du projet
Xcode. Par consquent, nous pouvons envoyer lobjet mainBundle, qui reprsente
lapplication installe, le message pathForResource:ofType an dobtenir le chemin
complet du chier audio sur lappareil (lignes 11 et 12). La ligne 14 envoie le message
play lobjet Sound pour que le chier soit jou.
La mthode initWithContentsOfFile de lobjet Sound montre comment convertir des
chiers audio, par exemple des chiers mp3, en sons systme. Pour cela, les chiers audio
iPhone Livre Page 127 Vendredi, 30. octobre 2009 12:04 12
128 Dveloppez des applications pour liPhone
doivent tre trs courts. En ralit, Apple suggre quils durent moins de 5 secondes.
Chaque son systme est cr partir de lURL de son emplacement. La ligne 1 du code
suivant illustre cette procdure avec une chane de chemin quelconque. La ligne 3 cre
lURL.
1 - (id) initWithContentsOfFile:(NSString *)path
2 {
...
3 NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO];
4 AudioServicesCreateSystemSoundID((CFURLRef)filePath, &soundID);
...
5 }
La ligne 4 convertit le chier audio en son systme. Les sons systme diffrent des chiers
audio standard car ils sont interprts et enregistrs dans le systme dexploitation lui-
mme. Pour les jouer, aucun lecteur multimdia nest ncessaire. Linvocation de la fonction
AudioServicesCreateSystemSoundID suft.
Cette fonction prend deux arguments. Le premier correspond lURL du chier audio, le
second est un pointeur sur un SystemSoundID. Dans lexemple, ce SystemSoundID est
lattribut soundID de lobjet Sound, qui est utilis ensuite pour jouer le son dans la
mthode play de lobjet Sound.
Comme le montre le code suivant, cette mthode play occupe une seule ligne de code. Un
appel la fonction AudioServicesPlaySystemSound, en lui passant un SystemSoundID,
suft pour que lutilisateur entende le son.
- (void) play {
AudioServicesPlaySystemSound(soundID);
}
Quel que soit le chier audio choisi comme son systme, voici les tapes de sa cration et
de son utilisation :
1. Obtenir une URL qui dsigne lemplacement du chier audio sur lappareil.
2. Gnrer le son systme et enregistrer son identiant.
3. Jouer le son systme.
Avec PhoneGap, le son systme est gnr chaque fois que vous demandez sa lecture, ce
qui nest pas trs efcace. Il est prfrable de crer le son une seule fois et de le jouer
ensuite autant de fois que vous voulez.
Nous lavons mentionn prcdemment, PhoneGap active le matriel GPS au dmar-
rage de lapplication. Cela se passe dans les trois premires lignes de la mthode
iPhone Livre Page 128 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 129
applicationDidFinishLaunching de la classe GlassAppDelegate. Le code suivant
montre que ces trois lignes initialisent un CLLocationManager, lenregistre dans lattribut
locationManager de la classe GlassAppDelegate et lui demande de commencer lactua-
lisation des informations GPS.
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startUpdatingLocation];
La classe CLLocationManager sert denveloppe au matriel GPS et Wi-Fi qui dtermine la
localisation courante de lappareil. Elle se fonde sur la puce GPS et les points daccs Wi-Fi
ouverts pour dterminer la latitude et la longitude actuelles.
La deuxime ligne du code prcdent demande lobjet locationManager dappeler la
mthode didUpdateToLocation de GlassAppDelegate chaque fois quun changement
de localisation est dtect. Pour cela, elle xe le dlgu de lobjet locationManager au
GlassAppDelegate courant reprsent par le mot cl self. Pour de plus amples informa-
tions concernant les dlgus, consultez les Chapitres 2 et 4 du livre The iPhone Developers
Cookbook: Building Applications with the iPhone SDK, dErica Sadun.
La mthode dlgue appele chaque changement de localisation se nomme didUpda-
teToLocation ; elle est dnie dans le chier GlassAppDelegate.m. Comme le montre le
code suivant, elle efface toute localisation dj enregistre, pour la remplacer par la locali-
sation actuelle passe la mthode dans le paramtre newLocation. Nous lavons vu
prcdemment, cette information est utilise par shouldStartLoadWithRequest dans sa
condition getloc.
-(void)locationManager:(CLLocationManager *)manager
// Note de lauteur.
// Il y a un bogue potentiel ici.
// Si newLocation == lastKnown alors
// lobjet newLocation est libr
// [newLocation retain] doit tre appel
// avant [lastKnownLoation release]
// Le code prsent est celui fourni
// par PhoneGap.
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{
[lastKnownLocation release];
lastKnownLocation = newLocation;
[lastKnownLocation retain];
}
iPhone Livre Page 129 Vendredi, 30. octobre 2009 12:04 12
130 Dveloppez des applications pour liPhone
Lactivation de lacclromtre est gre de manire semblable celle du GPS. Les trois
lignes de code suivantes demandent lacclromtre denregistrer ses donnes quarante
fois par seconde et xent ensuite le dlgu lobjet GlassAppDelegate courant, comme
pour le gestionnaire de localisation.
[[UIAccelerometer sharedAccelerometer] setUpdateInterval:1.0/40.0];
[[UIAccelerometer sharedAccelerometer] setDelegate:self];
Dans ce cas, la mthode appele est non pas didUpdateToLocation mais didAccele-
rate.
Le code suivant montre que la mthode didAccelerate ressemble normment la
mthode didUpdateToLocation. Elle obtient les informations de lacclromtre, mais,
au lieu de les enregistrer localement ct Objective-C de la bibliothque, elle les envoie
la partie JavaScript de manire comparable au traitement de la commande gotloc vue
prcdemment.
-(void) accelerometer:(UIAccelerometer *)accelerometer
didAccelerate:(UIAcceleration *)acceleration {
NSString * jsCallBack = nil;
NSLog(@"accelerating");
jsCallBack = [[NSString alloc]
initWithFormat:
@"gotAcceleration(%f,%f,%f);",
acceleration.x,
acceleration.y,
acceleration.z];
[webView stringByEvaluatingJavaScriptFromString:jsCallBack];
}
Si la mthode shouldStartLoadWithRequest reconnat dautres commandes, aucune
delles nest oprationnelle au moment de lcriture de ces lignes, et elles nont donc pas
t prsentes. Toutes les commandes dcrites dans cette section fonctionnent et sont
disponibles dans le programme dinstallation du modle Xcode pour les applications
PhoneGap.
En rsum
Ce chapitre a montr comment activer plusieurs fonctionnalits trs demandes de
liPhone ou de liPod Touch depuis une application JavaScript en utilisant la bibliothque
PhoneGap. Grce aux fonctionnalits natives de ces appareils, comme la localisation GPS,
lacclromtre, le vibreur et les sons, vous pouvez enrichir vos applications.
iPhone Livre Page 130 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 5 GPS, acclromtre et autres fonctions natives avec PhoneGap 131
En tudiant les exemples inclus avec PGDeviceCatalog et en connaissant Objective-C,
vous devez tre en mesure dajouter des fonctionnalits supplmentaires, comme le scan
du rseau Bonjour la recherche des appareils du voisinage, lajout, la suppression et
lobtention des contacts partir de lapplication Contacts, ou lexploitation dautres
comportements natifs disponibles aux applications Objective-C.
En se fondant sur lapproche dcrite dans ce chapitre, votre application JavaScript dispose
pratiquement des mmes possibilits quune application Objective-C.
iPhone Livre Page 131 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 132 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
6
Cartes Google
De nombreuses applications pour liPhone utilisent des cartes gographiques. Pour af-
cher ces cartes, il existe diffrentes mthodes, comme fermer lapplication en cours et
ouvrir lapplication de cartographie fournie par Apple, ou utiliser une carte Google. Ces
deux approches prsentent certaines limites. Ce chapitre explique comment crer une carte
Google et lutiliser la manire de lapplication de cartographie de liPhone sans fermer
lapplication en cours.
Section 1 : afcher une carte dans une application
JavaScript QuickConnect
Dans les applications hybrides pour liPhone, les programmeurs peuvent utiliser des cartes
de diffrentes manires. La solution la plus simple consiste ajouter un lien qui dbute par
http://maps.google.com et contient les informations gographiques souhaites. Lorsque
lutilisateur ouvre un tel lien, lapplication en cours se termine et lapplication de cartographie
standard est dmarre pour afcher la carte demande.
Cette approche simple est facile et rapide mettre en uvre. Toutefois, lapplication en
cours est termine, ce qui constitue gnralement une mauvaise conception logicielle.
iPhone Livre Page 133 Vendredi, 30. octobre 2009 12:04 12
134 Dveloppez des applications pour liPhone
Lapplication donne un sentiment dinachev, et les utilisateurs ont en ralit besoin dune
approche plus intgre.
Par ailleurs, mme si Google peut rpondre des requtes, comme "pizza", et placer de
nombreuses punaises, il est actuellement impossible de mettre plusieurs punaises sur des
emplacements que vous dnissez. Par exemple, vous pourriez souhaiter placer des punai-
ses en diffrents lieux dune ville. Si ces lieux ne correspondent pas des points dintrt
que lon peut rechercher, comme "pizza", vous ne pourrez pas placer les punaises en ajou-
tant une description de chaque lieu lURL soumise Google. Cette limitation est gnante
lorsque lon veut dnir les lieux punaiss par leur latitude et longitude.
Une autre solution consiste mettre en uvre dans lapplication un comportement
semblable celui obtenu avec une page web standard. LAPI AJAX de Google est alors
utilise pour embarquer une carte dans un <div> du contenu HTML afch. Ensuite,
chaque punaise est place indpendamment en passant par lAPI JavaScript de Google.
Si cette approche permet de garder lutilisateur dans lapplication, elle prsente galement
des inconvnients. Tout dabord, le UIWebView qui afche la carte nautorise pas le dle-
ment dans les <div>. Les vnements de toucher et de dplacement sont traits un
niveau infrieur et ne sont pas transmis la partie JavaScript de Google qui interagit avec
la carte embarque. Autrement dit, vous pouvez afcher la carte, mais il est impossible de
la dplacer pour changer la zone afche.
Par ailleurs, la taille des bulles dinformation sur les lieux proposes en standard par
Google pose problme. Elles sont dimensionnes pour un afchage dans un navigateur sur
un ordinateur. Lorsquelles sont afches sur liPhone, elles ont tendance recouvrir une
grande partie de la carte. La plupart des bulles apparaissent gnralement hors de lcran
et, en raison du problme de dlement mentionn prcdemment, ne sont pas visibles.
Sil est possible de limiter la longueur du contenu de ces bulles, il est impossible den
changer la taille.
La solution idale serait dembarquer la carte dans lapplication et de proposer laf-
chage de plusieurs punaises, comme dans la seconde option, tout en gardant les possi-
bilits de dlement et dafchage de la premire. Le framework QuickConnectiPhone
propose un composant qui permet de mettre en uvre cette solution par un seul appel
de JavaScript.
Le projet Xcode MapExample montre comment procder. Lcran principal de cet exem-
ple comprend un seul bouton HTML (voir Figure 6.1). Le gestionnaire onclick de ce
bouton est la fonction showTheMap dnie dans le chier main.js et dont le code est donn
ci-aprs. Elle congure quatre lieux : la ville de Rexburg dans lIdaho, le Wyoming, une
contre plus sauvage et une sandwicherie.
iPhone Livre Page 134 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 135
function showTheMap(event)
{
// Un lieu est dfini par une latitude,
// une longitude et une description.
var locationsArray = new Array();
rexburg = new Array();
rexburg.push(43.82211);
rexburg.push(-111.76860);
rexburg.push("Mairie");
locationsArray.push(rexburg);
var wyoming = new Array();
wyoming.push(42.86);
wyoming.push(-109.45);
wyoming.push("Place de Wyoming");
locationsArray.push(wyoming);
var wilderness = new Array();
wilderness.push(45.35);
wilderness.push(-115);
wilderness.push("Rivire du sans retour ");
locationsArray.push(wilderness);
var sandwichShop = new Array();
sandwichShop.push(42.86);
Figure 6.1
Lcran principal
de lapplication
MapExample comprend
un bouton HTML.
iPhone Livre Page 135 Vendredi, 30. octobre 2009 12:04 12
136 Dveloppez des applications pour liPhone
sandwichShop.push(-112.45);
sandwichShop.push("Sandwicherie");
locationsArray.push(sandwichShop);
showMap(event, locationsArray);
}
Chaque lieu dni est un tableau compos de trois lments : une latitude, une longitude et
une courte description afcher sur chaque punaise place. Ces lieux sont ajouts loca-
tionsArray. Si lordre des informations dnissant chaque lieu est g, le tableau locations-
Array nimpose aucun ordre.
Dans une application relle, les informations concernant chaque lieu pourraient provenir
dune base de donnes, dun ux RSS ou dune autre source. Vous pouvez mme les obte-
nir dynamiquement pendant lexcution de lapplication. Si vous connaissez des adresses,
utilisez lAPI JavaScript de gocodage de Google pour obtenir la latitude et la longitude
correspondantes (http://code.google.com/apis/maps/documentation/services.html#Geo
coding_Object). Toutefois, ces requtes prennent du temps. Il est prfrable de commen-
cer par obtenir les coordonnes des lieux intressants en lanant une tche lors de la
conception et denregistrer les rsultats avant de livrer lapplication.
Une fois que le tableau JavaScript contenant tous les lieux souhaits est cr, il est pass
la fonction showMap du framework, accompagn de lvnement qui a dclench lappel
la fonction showTheMap. ce stade, le framework prend le relais et, laide de la fonction
makeCall dcrite au Chapitre 4, demande la partie Objective-C dafcher une carte avec
des punaises sur chaque lieu (voir Figure 6.2).
Le framework afche la carte dans un objet Objective-C MapView. La classe MapView,
dcrite la Section 2, permet lutilisateur demployer le toucher et le balayement pour
contrler la carte la faon de lapplication de cartographie dApple. Par un double-
toucher sur un lieu de la carte, lapplication centre lafchage sur ce lieu et ralise un
zoom avant. Lutilisateur peut galement faire un double-toucher sur une punaise pour
centrer la carte et effectuer un zoom sur le lieu correspondant.
Lorsque lutilisateur touche simplement une punaise, une courte description est afche
dans une petite bote noire (voir Figure 6.3). Sil touche et fait glisser une punaise, il la
repositionne sur un nouveau lieu de la carte.
Lorsque lutilisateur na plus besoin de la carte, il slectionne le bouton Done pour faire
disparatre le MapView. Lafchage de lapplication revient dans ltat o il se trouvait au
moment o lapplication a afch la carte. Cela rsout les problmes dutilisation provo-
qus par la fermeture de lapplication, louverture de lapplication de cartographie, la
fermeture de celle-ci et le redmarrage de lapplication initiale.
iPhone Livre Page 136 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 137
Figure 6.2
Lapplication
MapExample place une
punaise sur chaque lieu.
Figure 6.3
Lapplication
MapExample afche
une courte description.
iPhone Livre Page 137 Vendredi, 30. octobre 2009 12:04 12
138 Dveloppez des applications pour liPhone
En invoquant la fonction JavaScript showMap du framework, lapplication embarque des
cartes. La Section 2 dtaille la conception et lutilisation de la classe Objective-C MapView
du framework, ainsi que dautres.
Section 2 : implmentation Objective-C du module
de cartographie de QuickConnect
Le module de cartographie de QuickConnect est constitu de trois classes :
MapView. Llment dafchage principal qui contient des images de la carte.
Pin. Une punaise qui doit tre afche sur un lieu.
InfoWindow. Une classe utilise pour afcher la courte description associe une
punaise.
La Figure 6.4 illustre les relations entre ces classes. Chaque MapView peut avoir plusieurs
Pin, et chaque Pin doit avoir au moins un MapView. Il existe galement une relation un
un entre les Pin et les InfoWindow. Autrement dit, pour chaque Pin, il doit y avoir au
moins un InfoWindow et, pour chaque InfoWindow, il doit y avoir au moins un Pin.
tant modulaire par nature, une application Objective-C doit interagir directement avec la
classe MapView et son API, dont la seule mthode se nomme initWithFrame:andLoca-
tions. Lorsque cette mthode est invoque, une carte est gnre, des punaises sont
places et de courtes descriptions sont disponibles lutilisateur lorsquil touche une
punaise. Par ailleurs, si lutilisateur ralise un double-toucher sur une punaise ou un lieu
de la carte, lafchage est centr sur ce lieu et un zoom avant est effectu. Le code ci-aprs
montre comment cette API de MapView est employe dans le framework QuickConnect.
linstar de la localisation GPS, du dbogage et des autres requtes dcrites au Chapi-
tre 2, lappel qui permet dafcher une carte embarque passe par un contrleur frontal et
des contrleurs dapplication. De mme, la commande showMap est associe show-
MapVCO dans le chier QCCommandMappings.m. La mthode doCommand de ce VCO est
courte et consiste principalement placer les informations de latitude, de longitude et de
description passes dans un tableau par la requte JavaScript. Pour cela, le premier
lment du tableau parameters est cart, car il sagit du QuickConnectViewController
Figure 6.4
Les classes du module
de cartographie et leurs
relations.
1 1 1
*
MapView InfoView Pin
iPhone Livre Page 138 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 139
de lapplication. La mthode doCommand, dont le code est donn ci-aprs, est extraite du
projet Xcode MapExample.
+ (id) doCommand:(NSArray*) parameters{
NSRange aRange = NSMakeRange(1, [parameters count]-1);
NSArray *locations = [parameters subarrayWithRange:aRange];
// Dimensionner le MapView la taille de lcran.
MapView *aMapView =
[[MapView alloc] initWithFrame:[[UIScreen mainScreen]applicationFrame]
andLocations:locations];
QuickConnectViewController *theController = [parameters objectAtIndex:0];
// Ajouter la vue de la carte la vue principale de lapplication.
[[[theController webView] superview] addSubview:aMapView];
return nil;
}
Puisque le QuickConnectViewController possde une rfrence au UIWebView qui af-
che et excute lapplication, il permet dobtenir un pointeur sur sa vue principale. Pour
cela, le message superview est envoy au UIWebView. Le nouveau MapView est ensuite
ajout la vue principale de lapplication en le passant comme paramtre du message
addSubview. Aprs lenvoi de ce message, le MapView apparat et occupe lintgralit de
lcran en masquant le UIWebView.
Puisque MapView est un module autonome, sa fonctionnalit peut tre facilement rutilise
dans de nombreuses applications diffrentes (voir Chapitre 2 pour les questions de modu-
larit). Il peut mme servir dans des applications Mac hybrides, aprs quelques modica-
tions mineures la procdure dafchage de la carte.
Toutes les cartes Google, quel que soit le contenu afch, sont des pages web. Par cons-
quent, lobjet MapView possde un attribut nomm webMapView qui correspond son
propre UIWebView. Il est diffrent de linstance de UIWebView qui afche lapplication.
Comme le montre le code suivant, webMapView afche le chier mapView.html prsent
dans le groupe MapView des ressources, et son dlgu est la classe MapView. Le groupe
MapView comprend un UIView embarquable et un WebViewDelegate qui traite tous les
vnements pour le UIWebView.
1 (id)initWithFrame:(CGRect)frame
2 andLocations:(NSArray*)aLocationList {
3 if (self = [super initWithFrame:frame]) {
4 OKToTouch = NO;
5 self.locations = aLocationList;
6 frame.origin.y -= 20;
7 UIWebView *aWebView = [[UIWebView alloc]
8 initWithFrame:frame];
iPhone Livre Page 139 Vendredi, 30. octobre 2009 12:04 12
140 Dveloppez des applications pour liPhone
9 self.webMapView = aWebView;
10 [aWebView release];
11
12 aWebView.userInteractionEnabled = NO;
13 // Fixer le dlgu de la vue web la
14 // vue web elle-mme.
15 [aWebView setDelegate:self];
16
17 // Dterminer le chemin du fichier mapView.html qui
18 // se trouve dans le rpertoire des ressources.
19 NSString *filePathString =
[[NSBundle mainBundle] pathForResource:@"mapView" ofType:@"html"];
20 MESSAGE(@"%@", filePathString);
21 // Crer lURL et la requte pour
22 // le fichier mapView.html.
23 NSURL *aURL = [NSURL fileURLWithPath:filePathString];
24 NSURLRequest *aRequest =
25 [NSURLRequest requestWithURL:aURL];
26
27 // Charger le fichier mapView.html dans la vue web.
28 [aWebView loadRequest:aRequest];
29
30 // Ajouter la vue web la vue de contenu.
31 [self addSubview:self.webMapView];
32 }
33 return self;
34 }
Vous pourriez penser que, pour des raisons de simplicit, la classe MapView nest pas
ncessaire, mais ce nest pas vrai. Puisque le UIWebView capture tous les vnements de
toucher et ne permet pas ces vnements dtre traits par les lments HTML quil afche,
le problme de dlement dcrit la Section 1 apparat.
Pour rsoudre ce problme, la ligne 12 du code prcdent dsactive le traitement des
vnements par le UIWebView contenu. Cela permet lobjet MapView contenant dobtenir
tous les vnements en tant que dlgu. Le dlgu a ensuite la charge dindiquer au
UIWebView que la page quil contient doit tre dcale.
Pour faire dler une carte, il faut dterminer que le doigt de lutilisateur sest dplac
aprs le toucher. Pour cela, la mthode standard touchesMoved:withEvent de MapView
doit tre implmente.
-(void)touchesMoved:(NSSet *)touches
withEvent:(UIEvent *)event{
if(OKToTouch){
if([touches count] == 1){
iPhone Livre Page 140 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 141
UITouch *touch = [touches anyObject];
CGPoint prevLoc = [touch previousLocationInView:self];
CGPoint curLoc = [touch locationInView:self];
double touchDeltaX = curLoc.x - prevLoc.x;
double touchDeltaY = curLoc.y - prevLoc.y;
NSString *javaScriptCall =
[[NSString alloc] initWithFormat:@"scroll(%f, %f)"
,touchDeltaX, touchDeltaY];
NSString *result = [webMapView
stringByEvaluatingJavaScriptFromString javaScriptCall];
if([result compare:@"true"] == 0){
int numPins = [pins count];
for(int i = 0; i < numPins; i++){
Pin *aPin = [pins objectAtIndex:i];
[aPin moveX:touchDeltaX andY:touchDeltaY];
[aPin.info moveX:touchDeltaX andY:touchDeltaY];
}
}
} else if([touches count] == 2){
// Pincement.
}
}
}
Cette implmentation de touchesMoved:withEvent commence par dterminer le mouve-
ment du toucher. Pour cela, elle calcule la diffrence entre lemplacement de lvnement
courant et celui de lvnement prcdent. Le rsultat est pass la page HTML dans
webMapView en envoyant le message stringByEvaluatingJavaSCriptFromString avec
un appel la fonction JavaScript scroll.
Cette fonction, dont le code donn ci-aprs se trouve dans le chier map.js du groupe
MapView, utilise lAPI JavaScript de cartographie de Google pour recentrer la partie visi-
ble de la carte. Elle applique les modications ncessaires aux valeurs x et y du centre de
la carte et indique ensuite lobjet map de se centrer sur cette nouvelle position.
function scroll(deltaX, deltaY){
try{
var centerPoint = map.fromLatLngToDivPixel(map.getCenter());
centerPoint.x -= deltaX;
centerPoint.y -= deltaY;
var centerLatLng = map.fromDivPixelToLatLng(centerPoint);
map.setCenter(centerLatLng);
}
iPhone Livre Page 141 Vendredi, 30. octobre 2009 12:04 12
142 Dveloppez des applications pour liPhone
catch(error){
return false;
}
return true;
}
En cas de succs, cette fonction JavaScript retourne true an que la suite de la mthode
touchesMoved:withEvent puisse demander chaque punaise afche de changer de
position.
En raison de la capture dsactive sur le UIWebView sous-jacent, pour que le dlement de
la carte puisse tre ralis, les punaises standard de Google ne sont pas en mesure de savoir
quelles ont t touches. Par consquent, les bulles de description ne peuvent pas tre af-
ches et masques pour ces punaises. Il est donc ncessaire de crer notre propre classe
Pin de gestion des punaises.
Cette classe, qui se trouve dans le groupe Classes:MapView, utilise limage pinInser-
ted.png, dnie dans Resources:Images, pour reprsenter les punaises lcran. Il est
trs facile de remplacer cette image par le chier de votre choix.
Un objet de classe Pin est initialis pour chaque emplacement envoy par lapplication
depuis le ct JavaScript. Pour cela, la mthode initWithFrame:andImage:andLoca-
tion, dont le code est donn ci-aprs, est invoque. Elle cre un UIImageView pour
limage de la punaise, xe son emplacement et active la capture des vnements en xant
son attribut userInteractionEnabled true.
-(id)initWithFrame:(CGRect)frame
andImage:(NSString*)anImage
andLocation:(MapViewLocation)aLocation{
if (self = [super initWithFrame:frame]) {
UIImageView *pinImage = [[UIImageView alloc]
initWithImage:[UIImage imageNamed:anImage]];
[self addSubview:pinImage];
[pinImage release];
location = aLocation;
self.userInteractionEnabled = YES;
self.backgroundColor = [UIColor clearColor];
}
return self;
}
En permettant les interactions avec lutilisateur sur un objet Pin, la punaise peut intercepter
et traiter les vnements. Lorsquune punaise est touche, la mthode touchesBegan:with-
Event de lobjet Pin est invoque et modie lafchage.
iPhone Livre Page 142 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 143
Cette fonction est dnie dans le chier Pin.m. Elle vrie que les vnements actuel et
prcdent ont lieu au mme emplacement sur lcran. Ainsi, le code de cette mthode nest
pas excut lorsque lutilisateur fait glisser son doigt sur lcran avec un mouvement de
type balayement.
Si lon suppose que le balayement na pas lieu, deux cas sont pris en charge par touches-
Began:withEvent. Le premier correspond lutilisateur qui touche simplement la
punaise. Le comportement souhait consiste alors lafchage dun message simple, qui a
t envoy avec la position par la partie JavaScript de lapplication. Pour cela, le mca-
nisme de rexion dObjective-C est utilis de manire envoyer un message single-
Touch la punaise elle-mme.
Le message performSelector:withObject:afterDelay est envoy la punaise au lieu
deffectuer directement un appel. Cela permet de diffrencier un toucher simple dun
toucher double. Comme le montre la ligne 13, lutilisateur dispose de 0,4 seconde pour
effectuer un double-toucher. Si ce double-toucher ne se produit pas, le premier toucher est
captur et le second est trait comme un autre toucher.
En revanche, si lutilisateur effectue un double-toucher sur la punaise dans la limite
des 0,4 seconde, un message cancelPreviousPerformRequestsWithTarget:selector:
object est envoy de manire arrter le passage du message singleTouch. Cette solu-
tion dlai/excution ou annulation reprsente la mthode standard pour dtecter le nombre
de frappes dans les touchers.
Lorsquun toucher simple est dtect, le message singleTouch est pass et la description
courte associe la punaise est afche. Dans le cas dun double-toucher, un zoom est
appliqu la carte et elle est centre sur lemplacement de la punaise.
1 -(void)touchesBegan:(NSSet *)touches
2 withEvent:(UIEvent *)event{
3 UITouch *touch = [touches anyObject];
4 CGPoint prevLoc = [touch previousLocationInView:self];
5 CGPoint curLoc = [touch locationInView:self];
6
7 if(CGPointEqualToPoint(prevLoc, curLoc)){
8 NSUInteger tapCount = [touch tapCount];
9 switch (tapCount) {
10 case 1:
11 [self performSelector:
12 @selector(singleTouch)
13 withObject:nil afterDelay:.4];
14 break;
15 case 2:
16 [NSObject cancelPreviousPerformRequestsWithTarget:self
17 selector:@selector(singleTouch)
iPhone Livre Page 143 Vendredi, 30. octobre 2009 12:04 12
144 Dveloppez des applications pour liPhone
18 object:nil];
19 // Zoom et centrage sur la punaise.
20 MESSAGE(@"double tap pin %i, %i",
21 location.x, location.y);
22
23 double latOffset = (location.y+42)/((MapView*)self.superview)
.pixelsPerDegLatitude;
24 double lngOffset = (location.x+10)/((MapView*)self.superview)
.pixelsPerDegLongitude;
25 double latitude = [[((MapView*)self.superview).northWest
objectAtIndex:0] doubleValue] - latOffset;
26 double longitude = [[((MapView*)self.superview).northWest
objectAtIndex:1] doubleValue] + lngOffset;
27 MESSAGE(@"latitude: %f longitude: %f northWest: %@",
28 latitude,
29 longitude,
30 ((MapView*)self.superview).northWest);
31 NSString *javaScriptCall = [[NSString alloc] initWithFormat:
@"zoomTo(%f, %f)",latitude, longitude];
32 NSString *mapDescription = [((MapView*)self.superview).
webMapView stringByEvaluatingJavaScriptFromString:
javaScriptCall];
33
34 [((MapView*)self.superview) setMapLatLngFrameWithDescription:
mapDescription];
35 [((MapView*)self.superview) updatePinLocations];
36
37 break;
38 default:
39 break;
40 }
41 }
42 }
En autorisant le zoom et le centrage par un double-toucher sur une punaise ou sur la carte,
les possibilits dutilisation de lapplication sont tendues. Lapplication de cartographie
standard ne permet pas ce type de centrage par un double-toucher ; seul le zoom est mis en
uvre. Lorsque lutilisateur effectue un double-toucher, il le fait gnralement suivre dun
balayement pour afcher la rgion autour de la zone qui lintresse. Notre application ne
souffre pas de cet inconvnient.
Il est galement possible de dplacer les punaises sur la carte en les faisant glisser. Cela se
passe dans la mthode touchesMoved:withEvent, qui est comparable au dlement de la
carte dcrit prcdemment. La diffrence rside dans le message cancelPreviousPer-
formRequestsWithTarget:selector:object, qui est de nouveau envoy de manire
viter lafchage de la description en raison de lappel la mthode touchesBegan avant
iPhone Livre Page 144 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 145
celui de touchesMoved. Si le message dannulation nest pas envoy, la courte description
est afche et la punaise est dplace. Lutilisateur risque de ne pas tre satisfait de ce
comportement.
1 -(void)touchesMoved:(NSSet *)touches
2 withEvent:(UIEvent *)event{
3 if([touches count] == 1){
4
5 [NSObject cancelPreviousPerformRequestsWithTarget:self selector:
@selector(singleTouch) object:nil];
6 moved = YES;
7 UITouch *touch = [touches anyObject];
8 CGPoint prevLoc = [touch previousLocationInView:self];
9 CGPoint curLoc = [touch locationInView:self];
10 double touchDeltaX = curLoc.x - prevLoc.x;
11 double touchDeltaY = curLoc.y - prevLoc.y;
12 [self moveX:touchDeltaX andY:touchDeltaY];
13 MapViewLocation mapLoc = self.location;
14 mapLoc.x += touchDeltaX;
15 mapLoc.y += touchDeltaY;
16 self.location = mapLoc;
17 if(self.info!= nil){
18 self.info.hidden = TRUE;
19 self.info.label.text = @"Unknown";
20 }
21 }
22 }
la manire du dlement de la carte, le dplacement dune punaise se fonde sur les posi-
tions prcdente et actuelle pour mettre jour lemplacement. Dans le cas du dlement
de la carte, lemplacement correspond au centre de la carte. Dans le cas du dplacement de
la punaise, il correspond au point dafchage suprieur gauche de la punaise et sa latitude
et sa longitude.
Puisque la punaise ne reprsente plus la position prcise lorigine sur la carte, la
description associe initialement la punaise est probablement invalide. Elle est par
consquent xe Unknown. Par ailleurs, si le court message safche pendant que lutili-
sateur fait glisser la punaise, il est ferm de manire rduire la charge processeur impo-
se par le trac de la punaise et du message pendant leur dplacement. Cette fermeture est
ralise la ligne 18.
Lattribut info de la classe Pin sert lafchage de la description fournie par la partie
JavaScript de lapplication. Il sagit dun objet InfoWindow qui est lui-mme un UIView
avec label pour seul attribut.
iPhone Livre Page 145 Vendredi, 30. octobre 2009 12:04 12
146 Dveloppez des applications pour liPhone
La mthode initWithFrame:andDescription de InfoWindow, donne ci-aprs et dnie
dans le chier InfoWindow.m prsent dans Classes:MapView, xe lemplacement de la
fentre pour lafchage de la description. Llment dinterface employ pour afcher
cette description est un UILabel.
-(id)initWithFrame:(CGRect)frame
andDescription:(NSString*)description{
if (self = [super initWithFrame:frame]) {
[self setBackgroundColor:[UIColor blackColor]];
CGRect labelFrame = CGRectMake(0, 0,
frame.size.width,
frame.size.height);
label = [[UILabel alloc] initWithFrame:labelFrame];
label.text = description;
label.backgroundColor = [UIColor clearColor];
label.textColor = [UIColor whiteColor];
label.textAlignment = UITextAlignmentCenter;
[self addSubview:label];
[label release];
}
return self;
}
En utilisant un UILabel pour afcher la description, les possibilits sont nombreuses.
Nous pouvons changer la police de caractres, son alignement, sa taille, sa couleur et bien
dautres attributs, comme les ombres portes. Nous pourrions dessiner le texte directement
au lieu dutiliser un UILabel, mais le code serait plus long. Grce au UILabel prdni,
lapplication rsultante est plus facile maintenir.
Les trois classes MapView, Pin et InfoWindow forment le module MapView. Elles contien-
nent le code ncessaire lafchage dune carte Google de base, mais il est facile de les
modier pour ajouter des comportements plus complexes.
Par exemple, vous pouvez modier la classe InfoWindow pour quelle prsente dautres
dtails, soit en changeant sa taille dafchage, soit en afchant un autre UIView complet,
comme dans le cas de lapplication de cartographie dApple. Il est galement possible de
changer la classe MapView de manire obtenir des indications routires. Mme si ces
extensions requirent des connaissances en Objective-C, elles ne sont pas techniquement
difciles.
Lajustement des positions de tous les objets Pin et de leur InfoWindow pendant le dlement
ou le zoom de la carte est un autre point intressant que nous navons pas encore abord.
Chacune de ces classes possde une mthode moveX:andY. Elles prennent en paramtre le
iPhone Livre Page 146 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 147
nombre de pixels, dans les directions x et y, ncessaires au dcalage de la punaise ou de la
fentre dinformation (voir le code ci-aprs).
Un programmeur Objective-C novice pourrait modier la position par une ligne de code
comme [self frame].origin.x += xChange. Cette ligne ne lance aucune exception, ne
provoque aucune erreur de compilation, mais ne modie pas la position de Pin ou de
InfoWindow.
Dans les classes Objective-C qui drivent de UIView, comme Pin et InfoWindow, le cadre
qui reprsente la position suprieure gauche, ainsi que la largeur et la hauteur, est appliqu
uniquement dans deux cas. Le premier correspond son initialisation avec le message
initWithFrame. Dans ce cas, la structure du cadre fournie en paramtres est utilise pour
dimensionner la vue. Le second correspond au remplacement de lattribut frame par un
autre, comme dans la mthode moveX:andY suivante.
- (void) moveX:(double) xChange andY:(double)yChange{
CGRect frame = [self frame];
frame.origin.x += xChange;
frame.origin.y += yChange;
self.frame = frame;
}
En raison de cette limitation, la manipulation de lattribut frame de la vue na aucun effet.
La mthode moveX:andY doit tre appele pour chaque dlement ou zoom de la carte.
Dans la mthode touchesMoved:withEvent de la classe MapView, chaque punaise reoit
ce message lors de la capture dun vnement.
for(int i = 0; i < numPins; i++){
Pin *aPin = [pins objectAtIndex:i];
[aPin moveX:touchDeltaX andY:touchDeltaY];
[aPin.info moveX:touchDeltaX andY:touchDeltaY];
}
La mthode touchesEnded:withEvent de la place MapView prend en charge le zoom de
la carte. Ce message est envoy par lappareil un objet MapView aprs le traitement de
tous les messages touchesBegan et touchesMoved.
Dans le code suivant, vous remarquerez quaprs avoir tabli quil sagit dun double-
toucher la position du toucher sur la carte est dtermine. Ensuite, la fonction JavaScript
zoomTo est appele, comme dans le cas du zoom dune punaise.
1 -(void)touchesEnded:(NSSet *)touches
2 withEvent:(UIEvent *)event{
3
iPhone Livre Page 147 Vendredi, 30. octobre 2009 12:04 12
148 Dveloppez des applications pour liPhone
4 if(OKToTouch){
5 UITouch *touch = [touches anyObject];
6 if ([touch tapCount] == 2){
7 // Zoom et centrage.
8 CGPoint curLoc = [touch locationInView:self];
9
10 double latOffset = curLoc.y/self.pixelsPerDegLatitude;
11 double lngOffset = curLoc.x/pixelsPerDegLongitude;
12
13 double latitude = [[northWest objectAtIndex:0] doubleValue] - latOffset;
14 double longitude = [[northWest objectAtIndex:1] doubleValue] + lngOffset;
15 NSString *javaScriptCall = [[NSString alloc] initWithFormat:
@"zoomTo(%f, %f)",latitude, longitude];
16 NSString *mapDescription = [webMapView stringByEvaluatingJava
ScriptFromString:javaScriptCall];
17
18 [self setMapLatLngFrameWithDescription:mapDescription];
19 [self updatePinLocations];
20 }
21 else{
22 NSLog(@"toucher");
23 }
24 }
25 }
Une fois le zoom termin, que ce soit dans le cas dun double-toucher pour lobjet Pin ou
MapView, un message updatePinLocations est envoy lobjet MapView (ligne 19 du
code prcdent). Le code suivant montre que cet appel provoque la mise jour de la posi-
tion de chaque punaise en fonction de sa latitude, de sa longitude et du facteur de zoom de
la carte.
Le facteur de zoom est reprsent par les attributs pixelsPerDegLatitude et pixels-
PerDegLongitude de la classe MapView xs lors dun appel prcdent la mthode setMap-
LatLngFrameWithDescription.
1 -(void) updatePinLocations{
2 int numPins = [pins count];
3 for(int i = 0; i < numPins; i++){
4 Pin *aPin = (Pin*)[pins objectAtIndex:i];
5 double latitudeDelta = [[northWest objectAtIndex:0] doubleValue] -
aPin.location.latitude;
6 double longitudeDelta = aPin.location.longitude - [[northWest
objectAtIndex:1] doubleValue];
7
8 double yPixels = latitudeDelta * pixelsPerDegLatitude;
9 double xPixels = longitudeDelta * pixelsPerDegLongitude;
iPhone Livre Page 148 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 6 Cartes Google 149
10 MapViewLocation aPinLocation = aPin.location;
11 aPinLocation.x = xPixels - 10 - 4;
12 // Le visuel de la punaise se trouve dans limage 10pixels
13 // partir de la gauche.
14 aPinLocation.y = yPixels - 42 + 10;
15 // Le visuel de la punaise se trouve dans limage 10pixels
16 // partir du bas.
17
18 CGRect pinFrame = aPin.frame;
19 pinFrame.origin.x = aPinLocation.x;
20 pinFrame.origin.y = aPinLocation.y;
21 aPin.frame = pinFrame;
22 aPin.location = aPinLocation;
23
24 CGRect infoFrame = aPin.info.frame;
25 infoFrame.origin.x = aPinLocation.x - 100;
26 infoFrame.origin.y = aPinLocation.y - 30;
27 aPin.info.frame = infoFrame;
28 }
29 }
Comme dans la mthode moveX:andY, le cadre doit tre retrouv, modi et initialis. Ces
oprations sont ralises aux lignes 18 22 du code prcdent pour la punaise et aux
lignes 24 27 pour le InfoWindow associ lobjet Pin.
La position des objets Pin et InfoWindow est mise jour lors de chaque zoom. Il est possi-
ble que certains dentre eux ne soient plus dans les limites de visibilit xes par le
MapView courant, mais ce nest pas un problme. Ils sont simplement afchs dans une
partie non visible, en dehors de lcran. Le code na pas besoin de les masquer.
En rsum
Ce chapitre a expliqu comment embarquer des cartes Google dans une application et
comment le module dafchage dune carte a t cr. Il a galement montr comment
manipuler les positions des vues personnalises et des vues standard.
En utilisant judicieusement lAPI JavaScript de Google avec une carte afche par un
UIWebView, il est possible deffectuer un zoom et un recentrage.
Puisque toutes ces fonctionnalits sont incluses dans le framework QuickConnect, il vous
suft dun seul appel JavaScript pour afcher une carte Google pleinement oprationnelle.
Si le ct JavaScript du framework est simple dutilisation, il est galement facile dutili-
ser le module de cartographie dans nimporte quelle application Objective-C pour
liPhone. En ralit, seules quelques lignes de code sont ncessaires.
iPhone Livre Page 149 Vendredi, 30. octobre 2009 12:04 12
150 Dveloppez des applications pour liPhone
Les cartes Google personnalises peuvent dsormais tre embarques dans nimporte
quelle application pour liPhone. La version 3.0 du systme dexploitation de liPhone
rend mme cette fonctionnalit encore plus facile.
iPhone Livre Page 150 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
7
Bases de donnes
La plupart des applications crites en JavaScript ont besoin dun serveur web pour enregis-
trer des donnes. Depuis la version 2.0 du systme dexploitation de liPhone et sa classe
UIWebView, il est possible denregistrer des donnes sur le tlphone sans passer par le
rseau. Autrement dit, lapplication que vous crez est une entit de premire classe sur
liPhone. Ce chapitre explique comment enregistrer et retrouver des donnes, et comment
crer des bases de donnes et des tables. Il fournit une enveloppe JavaScript simple
demploi pour accder la base de donnes SQLite disponible sur liPhone. Les premires
sections dcrivent lutilisation de la base de donnes, les dernires prsentent le code de
lenveloppe.
Section 1 : application BrowserDBAccess
Lapplication BrowserDBAccess a t cre pour vous aider comprendre lutilisation des
bases de donnes dans les applications JavaScript. Elle cre une base de donnes SQLite
nomme sampleDB, dans laquelle une table, score, est dnie. Cette base de donnes
existe dans le UIWebView et lutilisateur peut la consulter. Les bases de donnes cres de
cette manire sont persistantes entre les excutions de lapplication, mme si elles nont pas
t installes avec lapplication. Cette dernire peut ainsi retrouver les donnes enregistres
iPhone Livre Page 151 Vendredi, 30. octobre 2009 12:04 12
152 Dveloppez des applications pour liPhone
dans la base chaque excution. La Figure 7.1 montre lexcution de cette application
avant lenvoi dune requte la base de donnes.
La table score de lapplication BrowserDBAccess comprend deux champs. Le premier,
de type caractre nomm player_name, correspond la cl primaire. Le second, nomm
score, est de type entier. Puisque la cl primaire nest pas incrmente automatiquement,
sa valeur doit tre fournie chaque fois quun enregistrement est ajout. BrowserDBAccess
utilise plusieurs classes, mthodes et fonctions JavaScript prdnies pour accder aux
donnes de sampleDB.
Terminologie des bases de donnes
Le monde des bases de donnes possde sa propre terminologie. Les tables servent
regrouper des lments semblables. Chacun de ces lments est appel enregistrement.
Les enregistrements sont constitus de valeurs saisies dans des champs. Les champs sont
dnis par leur nom et leur type. Les enregistrements sont comparables aux lignes dune
feuille de calcul, les champs, aux colonnes. Les tables sont les feuilles de calcul. Si vous
ajoutez un nouvel enregistrement une table chiens, cela quivaut ajouter une
nouvelle ligne une feuille de calcul chiens. En ralit, ce nest pas vraiment identique,
mais sufsamment comparable pour faciliter la comprhension.
Figure 7.1
Lapplication
BrowserDBAccess avant
lexcution de la requte.
iPhone Livre Page 152 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 153
Une cl primaire identie de manire unique chaque enregistrement dune table. Il peut
sagir dun entier ou dune chane de caractres, mais les doublons sont interdits. Une cl
primaire peut correspondre, par exemple, la combinaison de votre nom dutilisateur et
de votre mot de passe ADC (Apple Developer Connection). Bien videmment, si deux
personnes avaient les mmes informations douverture de session, le rsultat serait
dramatique.
Une cl trangre est un autre lment. Elle est utilise pour lier des donnes enregistres
dans deux tables diffrentes. Imaginez les deux tables propritaires et chiens. La table
propritaires possde une cl primaire pour chaque enregistrement. Pour lier les chiens
et les propritaires, une cl trangre est ajoute la table chiens. Cette cl trangre
contient la cl primaire du propritaire dun chien dans la table propritaires. Cela qui-
vaut au numro didentication tatou dans loreille du chien et qui permet de retrouver
son propritaire.
Section 2 : utilisation des bases de donnes SQLite
avec WebView
Lutilisation des bases de donnes peut paratre intimidante. Un programmeur doit garder
lesprit toute une ribambelle de piges potentiels lors de lenregistrement ou de lobten-
tion des informations. En raison de ces cueils, les programmeurs choisissent souvent de
ne pas employer des bases de donnes pour le stockage de donnes simples.
Sur liPhone, la solution native pour le stockage des donnes des applications passe par
une base de donnes SQLite embarque, non un chier texte ou binaire. La rapidit et la
facilit dutilisation de ce moteur de bases de donnes peut conditionner le succs de vos
applications. Pour acclrer le dveloppement, le framework QuickConnectiPhone
propose une classe JavaScript qui vous vite tous les tracas associs lutilisation des
bases de donnes.
Le chier DataAccessObject.js, prsent dans le groupe QCiPhone des modles Dashcode
et Xcode, contient une enveloppe qui prend en charge laccs la base de donnes SQLite.
Les deux modles incluent automatiquement ce chier JavaScript dans le chier
index.html de lapplication. La classe DataAccessObject dnie par lenveloppe
comprend un constructeur et quatre mthodes (voir Tableau 7.1).
Cette classe JavaScript est employe dans le chier databaseDenition.js inclus dans votre
application par les modles. Cest dans ce chier que vous devez indiquer la ou les bases
de donnes utilises par votre application.
Le code suivant, extrait du chier databaseDenition.js de lapplication BrowserDBAccess,
montre comment utiliser le constructeur pour crer une base de donnes gre par le
iPhone Livre Page 153 Vendredi, 30. octobre 2009 12:04 12
154 Dveloppez des applications pour liPhone
Tableau 7.1 : API de DataAccessObject
Attribut/mthode Valeur de retour Description Paramtres
DataAccessObject
(dbName, dbVersion,
dbDescription, dbSize)
DataAccess-
Object
Cre un Data-
AccessObject
lorsquelle est
appele avec le mot
cl new.
dbName une chane
diden-tication unique
employe pour dsigner la
base de donnes.
dbVersion une chane
donne gnralement sous
forme dun nombre virgule
ottante.
dbDescription une
chane prcisant le rle de la
base de donnes.
dbSize la quantit mini-
male despace disque allou
la base de donnes (en
octets). Si ce paramtre est
absent ou si null est pass, la
taille par dfaut est utilise
(5 Mo).
getData(SQL,
parameterArray)
Aucune Cette mthode
permet dextraire
les informations,
conformment
linstruction SQL
passe, partir
dune base de
donnes cre dans
UIWebView.
SQL une chane de com-
mande SQL valide.
parameterArray un
tableau des valeurs utilises
par la commande SQL
dans le cas dune instruction
prpare.
setData(SQL,
parameterArray)
Aucune Cette mthode
permet denre-
gistrer des informa-
tions, conform-
ment linstruction
SQL passe, dans
une base de donnes
cre dans
UIWebView.
SQL une chane de com-
mande SQL valide.
parameterArray un
tableau des valeurs utilises
par la commande SQL
dans le cas dune instruction
prpare.
iPhone Livre Page 154 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 155
moteur WebKit dans les applications hybrides pour liPhone. Lutilisation du moteur de
base de donnes intgr au moteur se rvle approprie lorsque toutes les donnes sont
gnres par lapplication aprs son installation.
var sampleDatabase = new DataAccessObject("sampleDB", "1.0", "a sample database",2000);
Le code prcdent cre une base de donnes nomme sampleDB, ou louvre si elle existe
dj. Puisque WebKit prend en charge la cration et lutilisation de cette base de donnes,
il a besoin de deux lments dinformation. Le premier est le numro de version de la
base. Vous pouvez choisir nimporte quelle valeur ; dans notre exemple, il est x 1.0.
Le second indique la taille maximale prvue de la base de donnes ; dans notre exemple, il
est x 2000 octets.
La valeur retourne par lappel au constructeur est un DataAccessObject connect la
base de donnes SQLite sous-jacente et prt tre utilis. La modication de la base de
donnes est ensuite possible, comme le montre le code suivant, qui utilise la mthode
setData de DataAccessObject.
sampleDatabase.setData("CREATE TABLE IF NOT EXISTS score (player_name VARCHAR
PRIMARY KEY, score INTEGER);");
getNativeData(SQL,
parameterArray)
Aucune Cette mthode
permet dobtenir des
informations partir
dune base de don-
nes installe avec
lapplication.
SQL une chane de com-
mande SQL valide.
parameterArray un
tableau des valeurs utilises
par la commande SQL
dans le cas dune instruction
prpare.
setNativeData(SQL,
parameterArray)
Aucune Cette mthode
permet denregistrer
des informations
dans une base de
donnes installe
avec lapplication.
SQL une chane de com-
mande SQL valide.
parameterArray un
tableau des valeurs utilises
par la commande SQL
dans le cas dune instruction
prpare.
Tableau 7.1 : API de DataAccessObject (suite)
Attribut/mthode Valeur de retour Description Paramtres
iPhone Livre Page 155 Vendredi, 30. octobre 2009 12:04 12
156 Dveloppez des applications pour liPhone
La commande SQL correspond la cration dune table, mais la mthode setData est
employe pour toutes les requtes SQL qui modient les tables de la base, ajoutent ou
suppriment des donnes, ou modient la base dune manire ou dune autre.
Nous lavons dcrit au Chapitre 2, les fonctions de contrle mtier (BCF, Business Control
Function) peuvent tre utilises pour obtenir des donnes partir de la base. Cest prcis-
ment le rle de la BCF getScoresBCF (voir ci-aprs) ; vous la trouverez dans le chier
functions.js.
Cette BCF se fonde sur la mthode getData de DataAccessObject pour obtenir des enre-
gistrements partir de la table score. Lappel correspondant se trouve la ligne 3.
1 function getScoresBCF(parameters){
2 var SQL = SELECT * FROM score;
3 sampleDatabase.getData(SQL);
4 }
La Figure 7.2 illustre les donnes obtenues via cette BCF. Notez que getScoresBCF ne
retourne aucune valeur, car la mthode getData est asynchrone. Le framework QuickCon-
nectiPhone prend en charge la rception des donnes rsultantes de la requte SQL et les
passe aux objets de contrle associs la mme commande que la BCF. La fonction de
contrle de lafchage displayScoresVCF, dnie dans le chier functions.js, est asso-
cie la mme commande que getScoresBCF. Par consquent, le framework lui passe les
informations ds quelles sont disponibles.
Linsertion de donnes dans la table se fait de manire comparable. Pour insrer lenregis-
trement de la personne nomme Jane, la mthode setData doit tre appele de la manire
suivante :
sampleDatabase.setData("INSERT INTO score VALUES(Jane, 250)");
Les valeurs ne sont gnralement pas ges dans les instructions SQL. Le plus souvent,
elles sont saisies par lutilisateur. Bien quil soit possible de construire une instruction
SQL comme la prcdente partir des informations fournies par lutilisateur, cette solu-
tion est dangereuse. Le code suivant montre comment viter ce danger laide des instructions
prpares.
function setScoresBCF(parameters){
var name = document.getElementById(nameField).value;
var score = document.getElementById(scoreField).value;
var statementParameters = [name, score];
var SQL = "INSERT INTO score VALUES(?,?)";
sampleDatabase.setData(SQL, statementParameters);
}
iPhone Livre Page 156 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 157
Vous remarquerez quil diffre du code qui appelle setData pour crer la table score.
Dans la chane SQL, des points dinterrogation ont remplac le nom et le score qui taient
supposs apparatre. Il sagit de paramtres substituables employs dans les instructions
prpares pour indiquer o doivent tre insres les donnes du tableau statementPara-
meters. Le programmeur se charge dajouter au tableau les valeurs qui seront places,
dans lordre, dans la chane SQL. Cest pourquoi la variable name est ajoute au tableau
statementParameters avant la variable score.
Instructions prpares
Les instructions prpares amliorent normment la scurit des instructions SQL servant
enregistrer les donnes saisies par lutilisateur. En ralit, elles constituent un bon
moyen darrter les attaques par injection SQL et devraient tre utilises plus quelles ne
le sont actuellement.
Supposons que vous vouliez ajouter un enregistrement une table nomme
preferences_utilisateur, qui comprend les champs lieu, couleur et chanson. Vous pourriez
procder de la manire suivante :
"SELECT * FROM preferences_utilisateur WHERE nom = "+unNom
Cette manire de composer les instructions SQL est mauvaise, vraiment trs mauvaise. Elle
ouvre la porte aux attaques par injection SQL sur lintgralit de la base de donnes.
Figure 7.2
Lapplication
BrowserAccessExample
aprs avoir touch le
bouton Excuter la
requte.
iPhone Livre Page 157 Vendredi, 30. octobre 2009 12:04 12
158 Dveloppez des applications pour liPhone
Ces attaques permettent de pntrer dans les bases de donnes. Vous ne devez pas
composer les instructions SQL de cette manire.
Pour crer une chane SQL, voici la solution scurise :
"SELECT * FROM preferences_utilisateur WHERE nom =?)"
Vous devez galement crer un tableau qui contient les valeurs qui seront utilises la
place des points dinterrogation. Puisquelles se fondent sur une instruction prpare, les
appels setData et getData soccupent du reste.
Lorsquune instruction prpare est utilise, la chane SQL est analyse avant que les
points dinterrogation ne soient remplacs par les valeurs. Autrement dit, toute
commande SQL malveillante place dans les variables est dtecte et rejete ; pour la
base de donnes, linstruction SQL semble contenir une chane trange. Un appel avec des
points dinterrogation, tel que le prcdent, ne retourne aucun rsultat. En revanche, en
composant linstruction SQL par concatnation, un hacker peut facilement obtenir tout ce
quil souhaite partir dune table.
Les instructions prpares protgent les bases de donnes des intrusions connues sous le
nom attaques par injection SQL. Mme sil peut sembler idiot de protger notre petite base
de donnes contre les intrusions, ce nest pas le cas. Si quelquun russit obtenir un accs
non autoris un appareil ou au code qui sy excute, il trouvera toujours le moyen de
causer des dommages. Tous les dveloppements doivent se faire de manire scurise.
La suppression de donnes dans la base suit une procdure comparable. Puisque la base de
donnes est modie, la mthode setData est employe. Puisque lutilisateur saisit le
nom supprimer, une instruction prpare est utilise.
function deleteScoreBCF(parameters){
var name = document.getElementById(nameField).value;
var statementParameters = [blogName];
database.setData(DELETE FROM score where name =?,
statementParameters);
}
Section 3 : utilisation de bases de donnes SQLite
natives
Outre la possibilit de crer et dutiliser des bases de donnes dans le moteur WebKit
disponible dans toute application hybride pour liPhone, il est galement possible dutili-
ser des bases de donnes natives. Grce ces bases de donnes, les dveloppeurs dappli-
cations peuvent inclure des donnes existantes dans lapplication installe. Par exemple,
iPhone Livre Page 158 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 159
vous pourriez inclure dans votre application tout un ensemble de localisations GPS stan-
dard an daider les utilisateurs trouver des produits sur un march de vente au dtail. Au
lieu de tlcharger et denregistrer les donnes au dmarrage de lapplication, vous pouvez
fournir un chier de base de donnes SQLite avec votre application.
Dun point de vue fonctionnel, lapplication nativeDBAccess est identique BrowserDBAc-
cess, mais elle utilise un chier de base de donnes SQLite nomm sample.sqlite. La
Figure 7.3 montre la prsence de ce chier dans le groupe Resources du projet Xcode.
Le code JavaScript ncessaire la cration dun DataAccessObject qui enveloppe les
appels une base de donnes native diffre de celui de la Section 2 employ avec les bases
de donnes du moteur WebKit. Si la dnition de la base de donnes se fait toujours dans
le chier databaseDenition.js, dans le cas des bases de donnes natives seul le nom du
chier de base de donnes est indiqu. Les paramtres de version et de taille sont super-
us, car les bases de donnes natives ont une taille illimite (avec raison) et la gestion des
versions fait partie du processus de construction et de distribution de lapplication.
var sampleDatabase = new DataAccessObject("sample.sqlite");
Figure 7.3
Les ressources de lapplication nativeDBAccess.
iPhone Livre Page 159 Vendredi, 30. octobre 2009 12:04 12
160 Dveloppez des applications pour liPhone
Notez quaucun appel ne cre une table, car la table score existe dj dans le chier
sample.sqlite. Bien quil soit possible de crer des tables dans des bases de donnes nati-
ves, cette opration est inhabituelle. Les tables sont gnralement ajoutes aux chiers de
base de donnes avant la distribution de lapplication sur lApp Store.
Pour obtenir des donnes depuis une base native, la mthode est pratiquement identique
celle mise en place pour les bases de donnes WebKit. La seule diffrence, illustre dans le
code suivant, est que la mthode getData est remplace par la mthode getNativeData.
Pour le dveloppeur de lapplication, ces deux mthodes ont un comportement identique.
function getScoresBCF(parameters){
debug(Obtention des scores depuis la base de donnes);
var SQL = SELECT * FROM score;
sampleDatabase.getNativeData(SQL);
}
De mme que getData dcrite la Section 2, la mthode getNativeData est asyn-
chrone. Par consquent, ds que les donnes sont disponibles, le framework les passe
aux objets de contrle associs la mme commande que la BCF, dans ce cas
displayScoresVCF. La Figure 7.4 prsente la page gnre par cette VCF dans lappli-
cation nativeDBAccess.
Figure 7.4
Lapplication
nativeDBAccess aprs
avoir touch le bouton
dexcution de la requte.
iPhone Livre Page 160 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 161
Lajout et la suppression des donnes, ainsi que la modication de la base de donnes, se
font exactement de la mme manire qu la Section 2, except que la mthode setNative-
Data est invoque la place de la mthode setData. En tant que dveloppeur de lapplication,
les diffrences de comportements vous sont transparentes.
Section 4 : utilisation de DataAccessObject
avec les bases de donnes du moteur WebKit
Les sections prcdentes ont expliqu comment utiliser DataAccessObject pour manipu-
ler des bases de donnes SQLite WebKit ou natives, sans avoir connatre leurs dtails de
fonctionnement internes. Cette section rvle ces dtails et montre comment les utiliser. Si
vous souhaitez simplement exploiter DataAccessObject, sans volont den connatre le
fonctionnement, vous pouvez sauter cette section.
Grce la classe DataAccessObject, dnie dans le chier DataAccessObject.js du
groupe QCiPhone, le programmeur nest pas oblig de possder des connaissances dtailles
quant SQLite. Elle a t conue avec des mthodes et des constructeurs comparables
ceux de lenveloppe AJAX ServerAccessObject dcrite au Chapitre 8. En simpliant
lAPI, les programmeurs qui ne sont pas familiers de SQLite ont la possibilit denregistrer
des donnes sans passer par une longue phase dapprentissage.
Le constructeur de DataAccessObject est la plus simple de toutes ces mthodes. Il xe et
dnit les mthodes de lobjet comme des fonctions anonymes. Autrement dit, aucun attri-
but nest ncessaire pour enregistrer les paramtres passs au constructeur.
Fonctions anonymes
Lorsque quelquun est anonyme, cela signie que vous ne connaissez pas son nom.
Lorsquune fonction est anonyme, cela signie quelle na pas de nom. En JavaScript, une
fonction standard a un nom dclar laide dune ligne semblable la suivante :
function aboyer(){}
Dans ce cas, la fonction se nomme aboyer. Lorsquune fonction doit tre passe une
autre fonction, il est frquent demployer des fonctions sans nom dclar. Ces fonctions
sont anonymes.
Pour passer une fonction anonyme aboyer, nous utilisons le code suivant :
aboyer(new function(){
// Faire quelque chose ici.
});
iPhone Livre Page 161 Vendredi, 30. octobre 2009 12:04 12
162 Dveloppez des applications pour liPhone
Notez que les oprateurs de porte de la fonction anonyme, {}, sont contenus dans les
oprateurs de paramtre de la fonction aboyer, (). La fonction aboyer peut invoquer ou
enregistrer cette fonction comme bon lui semble.
Les fonctions anonymes ont accs aux variables locales dnies dans la fonction dans
laquelle elles ont t dclares. Par consquent, le code suivant est valide :
String type = doberman;
aboyer(new function(){
if(type == boxer){
}
else if(type == doberman){
}
...
});
Cette possibilit est pratique lorsque des fonctions ou des mthodes prennent des fonc-
tions en paramtres, comme nous le verrons plus loin dans cette section.
linstar de nombreux outils puissants, il est important de ne pas faire un usage excessif
des fonctions anonymes si elles ne sont pas ncessaires.
Nous avons vu au Tableau 7.1 et aux Sections 2 et 3 que DataAccessObject comprend
deux principaux groupes de mthodes. Lun prend en charge les donnes enregistres ou
obtenues avec une base de donnes WebKit, tandis que lautre soccupe des transferts
entre la partie JavaScript de lapplication et un chier de base de donnes SQLite fourni.
Les mthodes fondes sur WebKit utilisent principalement du code JavaScript et sont
examines en premier.
Les mthodes getData et setData sont des faades. Elles contiennent peu de code et se
fondent sur une troisime mthode pour raliser la plus grande partie du travail. Leur seule
tche vritable consiste assembler les valeurs enregistres dans la variable passThrough-
Parameters.
this.getData = function(SQL, preparedStatementParameters){
var passThroughParameters = generatePassThroughParameters();
this.dbAccess(SQL, preparedStatementParameters,
false, passThroughParameters);
}
Puisque le comit de normalisation du W3C responsable des spcications HTML 5 exige
que tous les appels aux fonctionnalits de base de donnes du moteur WebKit soient asyn-
chrones, certaines informations concernant ltat courant de lapplication doivent tre
iPhone Livre Page 162 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 163
passes avec les requtes pour quelles puissent tre utilises par la suite. La fonction
generatePassThroughParameters, dnie dans QCUtilities.js, runit ces valeurs.
Le code suivant montre que cela inclut la commande courante pour laquelle des objets de
commandes sont invoqus, le nombre de BCO dj appels, les paramtres passs toutes
les fonctions de contrle, comme globalParamArray, et un tableau contenant tous les
rsultats dj gnrs par les appels dautres BCF, comme globalBCFResults.
function generatePassThroughParameters(){
var passThroughParameters = new Array();
passThroughParameters.push(window.curCmd);
passThroughParameters.push(window.numFuncsCalled);
passThroughParameters.push(globalParamArray);
passThroughParameters.push(window.globalBCFResults);
return passThroughParameters;
}
Ces valeurs servent ensuite au framework pour garantir que les autres fonctions de
contrle associes la commande curCmd dans le chier mappings.js sont excutes
comme si tous les appels taient synchrones. Pour de plus amples informations concernant
cette procdure, consultez le Chapitre 2.
Le tableau passThroughParameters est transmis la mthode dbAccess, avec un indica-
teur qui prcise si les instructions contenues dans la variable SQL doivent tre traites
comme une modication des donnes dans la base. Dans la mthode getData, cet indicateur
est false.
La mthode dbAccess est au cur de la classe DataAccessObject pour les bases de
donnes du moteur WebKit. Elle effectue tout le travail demand par les appels getData
et setData.
Pour comprendre cette mthode, il faut tout dabord comprendre lAPI JavaScript sous-
jacente de SQLite. Cette API fait partie du standard HTML 5 venir et est implmente
dans le moteur WebKit employ par le UIWebView de toutes les applications hybrides pour
liPhone et le navigateur Mobile Safari. La dernire version de ce standard est disponible
ladresse http://www.w3.org/html/wg/html5/#sql. Ce document dcrit plusieurs objets et
mthodes recenss dans les tableaux suivants.
Database constitue llment de base de cette API. Le Tableau 7.2 dcrit une fonction
associe cet objet et lune de ces mthodes. openDatabase est une fonction de fabrique
qui instancie un objet Database notre place.
Selon le document de normalisation, tous les paramtres de openDatabase sont facultatifs.
Toutefois, il est peu judicieux de ne pas dclarer un nom de base de donnes. Si vous utili-
sez plusieurs bases de donnes dans diffrentes applications, chacune doit possder un
iPhone Livre Page 163 Vendredi, 30. octobre 2009 12:04 12
164 Dveloppez des applications pour liPhone
Tableau 7.2 : API de Database
Attribut/mthode Valeur de retour Description Paramtres
openDatabase
(dbName, dbVersion,
dbDescription, dbSize)
Objet Database Une fonction de fabrique
qui cre un objet Data-
base en vue de son utili-
sation ultrieure.
dbName une chane
didentication unique
employe pour dsigner
la base de donnes.
dbVersion une
chane, gnralement
donne sous forme dun
nombre virgule ot-
tante.
dbDescription une
chane prcisant lobjec-
tif de la base de donnes.
dbSize la quantit
minimale despace dis-
que allou la base de
donnes (en octets). Si ce
paramtre est absent ou si
null est pass, la taille
par dfaut est utilise
(5 Mo).
transaction(execution-
Callback, errorCallback,
successCallback)
Objet SQLTran-
saction
Cette mthode cre un
objet SQLTransaction
utilis pour les mises
jour et les requtes sur la
base de donnes.
executionCallback
une fonction qui contient
le code ncessaire
lexcution du SQL.
errorCallback une
fonction facultative qui
est appele lorsque la
transaction a chou.
Lannulation des opra-
tions sur la base de don-
nes nest pas effectue
dans cette mthode, car
cette procdure est auto-
matique en cas dchec.
successCallback
une fonction facultative
qui est appele lorsque la
transaction a russi.
iPhone Livre Page 164 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 165
nom distinct. Si dbName reste vide, il est possible quune mme base de donnes soit parta-
ge par toutes les applications. Elle risque donc de subir les oprations malencontreuses
des applications crites par dautres programmeurs. Pour protger vos bases de donnes,
vous devez utiliser une rgle comparable celle de la mme origine qui contraint les
appels AJAX dans un navigateur.
Cette rgle de protection applique aux bases de donnes stipule que seules les applica-
tions ayant la mme origine peuvent accder une base de donnes. Si vous utilisez des
bases de donnes dans des applications web hberges sur www.monsite.fr et sur
web.monsite.fr, ces bases sont accessibles par les diffrentes applications web. Autre-
ment dit, toutes les applications qui proviennent de monsite.fr peuvent accder toutes
les bases de donnes qui ont cette origine, quelle que soit lapplication qui a cr la base
de donnes, mme dans un sous-domaine de monsite.fr.
Dans les applications hybrides, lobjet UIWebView remplace le navigateur web et, par
consquent, il nexiste aucune rgle de mme origine qui limite les requtes AJAX. Cela
nest pas encore tabli, mais nous pouvons supposer que la restriction de mme origine sur
les bases de donnes nest pas plus effective. Cest pourquoi la seule protection de votre
base de donnes contre les accs par dautres applications rside dans lutilisation dun
nom et dune version inconnus des autres programmeurs. Vous devez donc donner un nom
et une version votre base de donnes.
La mthode transaction est employe par tous les appels SQL. En ralit, il est impossi-
ble dexcuter des instructions SQL sur des bases de donnes WebKit sans passer par un
objet SQLTransaction cr par la mthode transaction. Par consquent, dans les appli-
cations hybrides pour liPhone, tous les appels JavaScript concernant une base de donnes
sont automatiquement transactionnels.
Les dveloppeurs sont souvent proccups par lannulation des oprations sur la base de
donnes. En gnral, cette annulation est effectue lorsque le code crit par le program-
meur dtecte lchec dune transaction. Lorsque vous utilisez les fonctionnalits Java-
Script de base de donnes, ces annulations ne constituent pas un problme car les
transactions sen occupent automatiquement en cas dchec.
Vous ne devez pas excuter une instruction SQL ROLLBACK en cas dchec dune transac-
tion. Cette opration a dj t effectue et cela risque de provoquer des dysfonctionne-
ments. La fonction errorCallBack passe la mthode transaction nest pas utilise
dans ce but. Elle sert uniquement signaler les checs.
Lobjet SQLTransaction noffre quune seule mthode, executeSQL (voir Tableau 7.3).
Elle accepte toute instruction SQL que vous lui passez, mais il est imprudent dassem-
bler une instruction SQL et de lexcuter. Vous devez utiliser la place les instructions
iPhone Livre Page 165 Vendredi, 30. octobre 2009 12:04 12
166 Dveloppez des applications pour liPhone
prpares. Pour de plus amples informations concernant les instructions prpares, consul-
tez la Section 2.
Outre linstruction SQL, le paramtre facultatif arguments est pass. Il sagit dun tableau
de chanes de caractres qui vont remplacer les points dinterrogation inclus dans
linstruction SQL. Ils correspondent aux variables de linstruction prpare cre par
lappel executeSQL. Tous les appels executeSQL crent une instruction prpare,
mme lorsquil ny a aucun paramtre substituable. Son utilisation apporte donc plus de
sret, sans changer la rapidit de lapplication.
Les deux derniers paramtres dsignent les fonctions de rappel excutes lorsque
linstruction, non la transaction, russit ou choue. La fonction de succs reoit un objet
SQLResultSet de la part de la mthode executeSQL. Le Tableau 7.4 prsente lAPI de
SQLResultSet. La fonction dchec reoit un objet SQLError ; son API est dcrite au
Tableau 7.3 : API de SQLTransaction
Attribut/mthode Valeur de retour Description Paramtres
executeSQL(sqlStatement,
arguments, successCall-
back, errorCallback)
Aucune Cette mthode excute
une chane dinstruction
SQL quelconque.
sqlStatement une
chane contenant une ins-
truction SQL valide. Elle
peut inclure des points
dinterrogation (?) si elle
doit tre traite comme
une instruction prpare.
arguments un tableau
facultatif des valeurs uti-
lises pour remplacer les
points dinterrogation (?)
dans les instructions pr-
pares.
successCallback
une fonction facultative
qui est appele lorsque
lexcution de sqlSta-
tement a russi.
errorCallback une
fonction facultative qui
est appele lorsque lex-
cution de sqlStatement
a chou.
iPhone Livre Page 166 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 167
Tableau 7.6. Pour traiter les rsultats de lexcution de linstruction SQL, vous devez
implmenter ces fonctions et les indiquer dans lappel la mthode executeSQL.
Lobjet SQLResultSet contient les informations que vous avez demandes au travers de
linstruction SQL. Il inclut galement deux lments intressants : les attributs insertID
et rowsAffected.
Lorsque la cl primaire dune table est incrmentation automatique et quun enregistre-
ment est ajout cette table, lattribut insertID du SQLResultSet contient la valeur
gnre pour la cl. Ce fonctionnement est trs utile lorsque la cl est requise pour ajouter
des donnes associes dans dautres tables.
Aprs lexcution russie dune instruction SQL dinsertion ou de mise jour, lattribut
rowsAffected contient le nombre de lignes qui ont t ajoutes ou modies. Cela permet
de valider le comportement des instructions SQL complexes.
Le troisime attribut de SQLResultSet se nomme rows. Il contient un SQLResultSetRow-
List, qui reprsente un tableau denregistrements. Le Tableau 7.5 montre que son attribut
Tableau 7.4 : API de SQLResultSet
Attribut/mthode Valeur de retour Description Paramtres
insertID Aucune Un attribut entier en lec-
ture seule qui contient
lidentiant de lenregis-
trement ajout si le
champ correspondant est
incrmentation automa-
tique.
Aucun
rowsAffected Aucune Un attribut entier en lec-
ture seule qui contient le
nombre de lignes ajou-
tes ou modies par une
opration de type mise
jour.
Aucun
rows Aucune Un attribut SQLResult-
SetRowList qui contient
toutes les lignes retour-
nes par une instruction
de type requte.
Aucun
iPhone Livre Page 167 Vendredi, 30. octobre 2009 12:04 12
168 Dveloppez des applications pour liPhone
length prcise le nombre denregistrements obtenus par une instruction de type SELECT. Il
correspond au nombre de lignes contenues dans le tableau.
Il offre galement la mthode item pour accder chaque ligne des rsultats. Grce cette
mthode et lattribut, il est facile ditrer sur les lignes et leurs valeurs laide de boucles
for. Voici la solution gnralement employe pour effectuer ces itrations :
1 for( var i = 0; i < aResultSet.length; i++){
2 var aRow = aResultSet.item(i);
3 for(key in aRow){
4 var aValue = aRow[key];
5 // Exploiter la cl et la valeur.
6 }
7 }
Bien que le code prcdent puisse tre considr par beaucoup comme une solution stan-
dard, son excution nest pas optimale car, la ligne 1, la taille du jeu de rsultats est obte-
nue chaque tour de boucle externe. Un autre gaspillage est gnr par la rptition de la
boucle for-each la ligne 3.
Les boucles JavaScript for-each sont particulirement gourmandes en cycles processeur,
notamment lorsquelles sont employes dans dautres boucles. Plus loin dans cette section,
la description de la mthode dbAccess montrera comment optimiser ce code.
Si lexcution de linstruction SQL provoque une erreur, quelle quen soit la raison, un
objet SQLError est gnr la place de lobjet SQLResultSet. De mme quun SQLRe-
sultSet est pass la fonction de russite indique en argument de la mthode executeSQL,
un SQLError est pass la fonction dchec.
Tableau 7.5 : API de SQLResultSetRowList
Attribut/mthode Valeur de retour Description Paramtres
length Aucune Un attribut en lecture
seule qui contient le
nombre denregistre-
ments obtenus par une
instruction de type
requte.
Aucun.
item(index) Tableau Une mthode qui
retourne un enregistre-
ment sous forme de
tableau associatif ou de
mappe JavaScript.
index lindice de
lenregistrement dans le
jeu des rsultats retour-
ner.
iPhone Livre Page 168 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 169
La fonction de succs ne reoit jamais un SQLError et la fonction derreur ne reoit jamais
un SQLResultSet. Ainsi, chacune de ces fonctions remplit un seul objectif et devient donc
plus facile crer, crire et maintenir.
Lobjet SQLError contient deux attributs qui correspondent un numro de code derreur
et un message derreur gnrs par SQLite (voir Tableau 7.6).
code et message sont utiles aux programmeurs, mais ne doivent pas tre prsents aux
utilisateurs, car ils ne sauront pas ce quils reprsentent. Ces attributs doivent servir jour-
naliser lerreur et afcher une information utile aux utilisateurs.
La mthode dbAccess de DataAccessObject les utilise. Nous lavons mentionn prc-
demment dans cette section, cette mthode prend cinq arguments et ralise le travail des
Tableau 7.6 : API de SQLError
Attribut/mthode Valeur de retour Description Paramtres
code Aucune Un attribut en lecture seule qui contient le numro
du code de lerreur. Les codes possibles sont :
Aucun.
0 la transaction a chou pour une raison inconnue.
1 Linstruction a chou pour une raison inconnue.
2 Linstruction a chou car la version attendue de
la base de donnes ne correspond pas sa version
relle.
3 Linstruction a chou car le nombre de donnes
retournes tait trop important. Essayez dutiliser le
modicateur SQL LIMIT.
4 Linstruction a chou car les limites mmoire
ont t atteintes et lutilisateur na pas accept de les
augmenter.
5 Linstruction a chou en raison dun chec du
verrouillage dans la transaction.
6 Une instruction INSERT, UPDATE ou REPLACE a
chou car elle ne respecte pas une contrainte,
comme un cas de cl unique duplique.
message Aucune Un attribut en lecture seule qui contient un message
derreur appropri.
Aucun.
iPhone Livre Page 169 Vendredi, 30. octobre 2009 12:04 12
170 Dveloppez des applications pour liPhone
mthodes de faade getData et setData. Son quatrime argument indique si la requte
modie ou consulte la base de donnes. Sa valeur est xe par la fonction de faade qui
invoque dbAccess.
En examinant la mthode dbAccess, vous constaterez quelle emploie plusieurs fonctions
anonymes. La premire est passe la ligne 3 en premier et seul paramtre de la mthode
transaction. Il pourrait sembler plus facile de la dnir comme une fonction normale
ailleurs dans le code et de la passer en premier argument, mais, dans ce cas, le code restant
serait difcile, voire impossible, implmenter car des variables accessibles grce aux
fonctions anonymes ne le seraient alors plus. La ligne 2 du code suivant instancie lobjet
QueryResult, qui est utilis comme valeur de retour de la mthode dbAccess.
Pour quun objet QueryResult soit vritablement utile, il doit tre disponible depuis
lintrieur de la fonction executeSQL de la transaction. Sans les fonctions anonymes, la
seule manire de procder consiste le rendre global.
Sil est dclar de manire globale, un seul accs la base de donnes ne peut avoir lieu
la fois. Puisque tous les accs la base de donnes sont asynchrones, ce fonctionnement
est impossible garantir. Par consquent, la meilleure approche consiste opter pour des
fonctions anonymes. Cette mme logique sapplique aux fonctions passes la mthode
executeSQL de la transaction elle-mme.
La mthode executeSQL de lobjet Transaction peut recevoir deux fonctions en paramtres.
Les bonnes pratiques stipulent quelles doivent toujours tre passes. Le second paramtre
correspond la fonction qui traite les rsultats lorsque la requte se passe parfaitement (voir
Tableau 7.6). La dclaration de cette fonction commence la ligne 10 du code ci-aprs.
Dans la fonction de russite, tout identiant gnr par linstruction SQL est enregistr
dans le QueryResult instanci la ligne 7. Si des lignes de la base de donnes sont modi-
es, leur nombre est galement indiqu, mais uniquement si le paramtre treatAsChan-
geData de la mthode dbAccess est x true.
Si des donnes nont pas t modies, une requte a d tre excute. Les lignes 23 51
prennent en charge ce cas. Dans ces lignes, un tableau JavaScript deux dimensions est
cr et associ au QueryResult. Toutes les valeurs qui se trouvent dans le jeu de rsultats
SQLResult y sont enregistres. En transfrant les donnes dans un tableau JavaScript stan-
dard, vous pouvez accder ces donnes dans un autre code, sans connatre la structure de
lobjet SQLResult ni les champs renvoys par la requte. Si vous souhaitez connatre les
noms des champs, ils sont galement prsents dans lobjet QueryResult. Les noms et les
valeurs des champs conservent lordre dans lequel ils se trouvent dans le SQLResult.
1 this.dbAccess = function(SQL, preparedStatementParameters,
2 treatAsChangeData, passThroughParameters){
3 if(!this.db){
iPhone Livre Page 170 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 171
4 this.db = openDatabase(dbName, dbVersion,
5 dbDescription, dbSize);
6 }
7 var queryResult = new QueryResult();
8 this.db.transaction(function(tx) {
9 tx.executeSql(SQL, preparedStatementParameters,
10 function(tx, resultSet) {
11 if(treatAsChangeData){
12 try{
13 queryResult.insertedID = resultSet.insertId;
14 queryResult.rowsAffected =
15 resultSet.rowsAffected;
16 }
17 catch(ex){
18 // Il doit sagir une mise jour.
19 queryResult.rowsAffected =
20 resultSet.rowsAffected;
21 }
22 }
23 else{
24 // La base de donnes na pas t modifie.
25 // Il doit sagir dune requte.
26 queryResult.numRowsFetched =
27 resultSet.rows.length;
28 var dataArray = new Array();
29 queryResult.numResultFields = 0;
30 queryResult.fieldNames = new Array();
31 if(queryResult.numRowsFetched > 0){
32 // Obtenir les identifiants des champs dans le jeu de rsultats.
33 firstRecord = resultSet.rows.item(0);
34 var numFields = 0;
35 for(key in firstRecord){
36 queryResult.fieldNames.push(key);
37 numFields++;
38 }
39 queryResult.numResultFields = numFields;
40 var numRecords =
41 queryResult.numRowsFetched;
42 for(var i = 0; i < numRecords; i++){
43 var record = resultSet.rows.item(i);
44 var row = new Array();
45 dataArray.push(row);
46 for(var j = 0; j < numFields; j++){
47 row.push(
48 record[queryResult.fieldNames[j]]);
49 }
50 }
iPhone Livre Page 171 Vendredi, 30. octobre 2009 12:04 12
172 Dveloppez des applications pour liPhone
51 }
52 queryResult.data = dataArray;
53 }
54 if(window.callFunc){
55 var theResults = new Array();
56 theResults.push(queryResult);
57 theResults.push(passThroughParameters);
58 requestHandler(passThroughParameters[0],
59 passThroughParameters[2], theResults);
60 }
61 }// Fin de la fonction de rappel en cas de succs de lexcution.
62 , function(tx, error) {
63 queryResult.errorMessage = error.message;
64 if(window.callFunc){
65 var theResults = new Array();
66 theResults.push(queryResult);
67 theResults.push(passThroughParameters);
68 requestHandler(passThroughParameters[0],
69 passThroughParameters[2], theResults);
70 }
71 }// Fin de la fonction de rappel en cas dchec de lexcution.
72 );// Fin de lappel principal executeSql.
73 });// Fin de la fonction de rappel de la transaction.
74 }// Fin de la mthode dbAccess.
Quel que soit le type de linstruction SQL excute, modication ou interrogation de la
base de donnes, lobjet QueryResult cr au dbut de la fonction est envoy par le
framework toutes les fonctions de contrle restantes non invoques. Cela se passe aux
lignes 58 et 59 laide de la fonction requestHandler dcrite au Chapitre 2.
La ligne 62 dbute la dclaration de la fonction de traitement des erreurs pour lobjet
Transaction. Cette fonction doit insrer le message derreur gnr par SQLite dans le
QueryResult et le transmettre aux fonctions de contrle restantes. Pour de plus amples
informations concernant les fonctions de contrle, consultez le Chapitre 2.
Section 5 : utilisation de DataAccessObject
avec les bases de donnes natives
Pour accder aux bases de donnes natives, il faut moins de code JavaScript que pour acc-
der aux bases de donnes du moteur WebKit. Une grande partie du travail est effectue du
ct Objective-C du framework.
iPhone Livre Page 172 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 173
linstar de getData et de setData, les mthodes getNativeData et setNativeData
sont des faades. Toutefois, elles appellent non pas la mthode dbAccess de DataAccess-
Object, mais la fonction getDeviceData dnie dans le chier QCUtilities.js.
this.getNativeData =
function(SQL, preparedStatementParameters){
getDeviceData(dbName, SQL, preparedStatementParameters);
}
this.setNativeData =
function(SQL, preparedStatementParameters){
setDeviceData(dbName, SQL, preparedStatementParameters);
}
La fonction getDeviceData est constitue de deux parties. La premire, reprsente par
les lignes 4 16, construit un tableau des informations ncessaires lexcution de la
requte en Objective-C. Cela comprend notamment les paramtres gnraux dcrits la
section prcdente. Ces paramtres sont requis, car, comme dans le traitement des requtes
aux bases de donnes du moteur WebKit, la requte est asynchrone. Pour de plus amples
informations concernant les appels asynchrones, consultez le Chapitre 2.
Le tableau cr contient le nom de la base de donnes, linstruction SQL excuter, les
paramtres de linstruction SQL prpare et les paramtres gnraux. La section prc-
dente de ce chapitre a donn les explications concernant les instructions prpares.
1 function getDeviceData(dbName, SQL,
2 preparedStatementParameters, callBackParams){
3 if(dbName && SQL){
4 var dataArray = new Array();
5 dataArray.push(dbName);
6 dataArray.push(SQL);
7 if(preparedStatementParameters){
8 dataArray.push(preparedStatementParameters);
9 }
10 else{
11 // Placer un paramtre substituable.
12 dataArray.push(new Array());
13 }
14 var callBackParameters =
15 generatePassThroughParameters();
16 dataArray.push(callBackParameters);
17
18 var dataString = JSON.stringify(dataArray);
19 makeCall("getData", dataString);
20 }
21 return null;
22 }
iPhone Livre Page 173 Vendredi, 30. octobre 2009 12:04 12
174 Dveloppez des applications pour liPhone
Lorsque les donnes sont prtes, elles sont converties en une chane JSON passe la
fonction makeCall. Nous lavons vu au Chapitre 4, cette fonction active le ct Objective-
C du framework. Il sagit l de la deuxime partie importante de la fonction getDevice-
Data. Sans elle, les bases de donnes natives seraient inaccessibles. Pour de plus amples
informations concernant JSON, consultez lAnnexe A.
linstar des fonctions du Chapitre 4 qui accdent aux donnes natives, des objets de
contrle Objective-C sont ncessaires lobtention des donnes depuis la base. Ces deux
objets, SetDataBCO et GetDataBCO, interagissent avec la base de donnes, quelle soit
modie ou consulte. Ce fonctionnement est comparable celui des fonctions JavaScript
getData et setData.
+ (id) doCommand:(NSArray*) parameters{
if( [parameters count] >= 3){
NSString *dbName = [parameters objectAtIndex:1];
NSString *SQL = [parameters objectAtIndex:2];
NSArray *perparedStatementValues = nil;
if([parameters count] == 4){
perparedStatementValues = [parameters objectAtIndex:3];
}
SQLiteDataAccess *aDBAccess =
[SQLiteDataAccess getInstance:dbName isWriteable:YES];
return [aDBAccess getData:SQL withParameters:perparedStatementValues];
}
return nil;
}
@end
Par ailleurs, comme les fonctions JavaScript getData et setData, le code de traitement
dans ces BCO est court. La commande doCommand permet dobtenir le nom de la base de
donnes, linstruction SQL et les paramtres de linstruction prpare provenant de la
requte JavaScript.
Lorsque tous ces lments dinformations sont disponibles, la mthode getData de lobjet
SQLiteDataAccess est invoque. Cet objet est essentiellement un clone de lobjet Java-
Script DataAccessObject. Il offre les mthodes getData et setData, mais, contrairement
la version JavaScript, la version Objective-C est un singleton. Pour de plus amples infor-
mations concernant les singletons, consultez le Chapitre 4.
Les mthodes getData et setData de SQLiteDataAccess sont des faades pour la
mthode dbAccess. De mme que la mthode JavaScript dbAccess, la version Objective-
C est particulirement complexe. Cela provient de la complexit de lAPI SQLite dnie
iPhone Livre Page 174 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 175
par la bibliothque dynamique libsqlite3.0.dylib fournie avec chaque iPhone et iPod Touch
(voir Tableau 7.7).
Tableau 7.7 : API de SQLite3
Objet/fonction Valeur de retour Description Paramtres
sqlite3 Aucune Un objet qui reprsente
la base de donnes
SQLite en mmoire.
Aucun.
sqlite3_open
(filePath, &aDatabase)
int SQLITE_OK
en cas de succs
de louverture
Ouvre le chier de base
de donnes indiqu par
filePath et enregistre
le pointeur dans
aDatabase.
filePath le chemin
complet du chier de base
de donnes SQLite sur la
machine.
aDatabase une rfrence
vers un pointeur SQLite3
qui reprsente la base de
donnes en mmoire.
sqlite3_close
(aDatabase)
void Ferme les connexions
au chier de base de
donnes SQLite.
aDatabase un pointeur
SQLite3 x dans la fonc-
tion sqlite3_open.
sqlite3_errmsg
(aDatabase)
const char * Obtient la dernire
erreur gnre.
aDatabase un pointeur
SQLite3 vers la base de
donnes dont on souhaite
obtenir un message
derreur.
sqlite3_stmt Aucune Une seule instruction
SQL prpare.
Aucun.
sqlite3_prepare_v2
(aDatabase, SQLChar,
-1, &statement, NULL)
int SQLite_OK
en cas de succs
Interprte linstruction
SQL.
aDatabase un pointeur
SQLite3 vers la base de
donnes.
SQLChar une chane
const char * de carac-
tres UTF8 qui reprsente
linstruction SQL.
sqlite3_column_count
(statement)
int Compte le nombre
de champs dans le jeu
de rsultats dune
requte.
statement un pointeur
sqlite3_stmt.
iPhone Livre Page 175 Vendredi, 30. octobre 2009 12:04 12
176 Dveloppez des applications pour liPhone
sqlite3_column_name
(statement, i)
const char * Obtient le nom dun
champ.
statement un pointeur
sqlite3_stmt.
i un entier qui
reprsente le numro du
champ.
sqlite3_changes
(database)
int Obtient le nombre
denregistrements
affects par la modi-
cation dune table.
aDatabase un pointeur
SQLite3 vers la base de
donnes.
sqlite3_step
(statement)
int SQLITE_ROW
lorsquune ligne
est disponible
Dplace le curseur vers
lenregistrement sui-
vant dans le jeu de
rsultats.
statement un pointeur
sqlite3_stmt.
sqlite3_column_type
(statement, i)
int
Valeurs
possibles:
SQLITE_INTEGER
SQLITE_FLOAT
SQLITE_BLOB
SQLITE_NULL
SQLITE_TEXT
Obtient le type dun
champ (colonne)
dans le jeu de rsultats
dune instruction.
statement un pointeur
sqlite3_stmt.
i le numro du champ
dont on souhaite obtenir
les donnes.
sqlite3_column_int
(statement, i)
int Obtient la valeur dun
champ de type entier.
statement un pointeur
sqlite3_stmt.
i le numro du champ
dont on souhaite obtenir
les donnes.
sqlite3_column_double
(statement, i)
double Obtient la valeur dun
champ de type rel.
statement un pointeur
sqlite3_stmt.
i le numro du champ
dont on souhaite obtenir
les donnes.
Tableau 7.7 : API de SQLite3 (suite)
Objet/fonction Valeur de retour Description Paramtres
iPhone Livre Page 176 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 177
sqlite3_column_text
(statement, i)
const unsigned
char *
Obtient la valeur dun
champ de type chane
de caractres.
statement un pointeur
sqlite3_stmt.
i le numro du champ
dont on souhaite obtenir
les donnes.
sqlite3_column_blob
(statement, i)
byte * Obtient les octets dun
champ de type BLOB
(binary large object).
statement un pointeur
sqlite3_stmt.
i le numro du champ
dont on souhaite obtenir
les donnes.
sqlite3_column_bytes
(statement, i)
int Obtient le nombre
doctets de la valeur dun
champ de type BLOB.
statement un pointeur
sqlite3_stmt.
i le numro du champ dont
on souhaite obtenir les
donnes.
sqlite3_finalize
(statement)
void libre les ressources
associes linstruction.
statement un pointeur
sqlite3_stmt.
sqlite3_bind_blob
(statement, parameter-
Index, aVariable, byte-
Length, transienceKey)
int Lie un pointeur sur un
tableau doctets un
paramtre substituable
dune instruction pr-
pare.
statement un pointeur
sqlite3_stmt.
parameterIndex
lindice du paramtre
substituable dans
linstruction prpare.
aVariable un pointeur sur
le tableau doctets
enregistrer dans la base de
donnes.
byteLength le nombre
doctets enregistrer.
transienceKey un
indicateur prcisant si les
donnes insres doivent
tre copies avant
linsertion an dviter
leur modication pendant
lenregistrement.
Tableau 7.7 : API de SQLite3 (suite)
Objet/fonction Valeur de retour Description Paramtres
iPhone Livre Page 177 Vendredi, 30. octobre 2009 12:04 12
178 Dveloppez des applications pour liPhone
Cette bibliothque C contient toutes les fonctions utilises pour laccs aux bases de
donnes SQLite. Elle prend galement en charge les transactions et les instructions prpa-
res. Le code ci-aprs montre comment employer cette API avec les instructions prpa-
res. Il provient de la mthode dbAccess de lobjet SQLiteDataAccess. Comme le stipule
lAPI, la fonction sqlite3_prepare_v2 attend des pointeurs sur la base de donnes, sur
linstruction SQL excuter et sur un pointeur vers une variable sqlite3_stmt. En cas
derreur au cours de lexcution de linstruction SQL, sqlite3_prepare_v2 retourne un
code numrique qui reprsente lerreur.
int numResultColumns = 0;
sqlite3_stmt *statement = nil;
const char* SQLChar = [SQL UTF8String];
if (sqlite3_prepare_v2(database, SQLChar, -1,
&statement, NULL) == SQLITE_OK) {
...
}
sqlite3_bind_double
(statement, parameter-
Index, aVariable)
int Lie une valeur relle
un paramtre substi-
tuable dune
instructionprpare.
statement un pointeur
sqlite3_stmt.
parameterIndex
lindice du paramtre
substituable dans
linstruction prpare.
aVariable un nombre
rel enregistrer dans la
base de donnes.
sqlite3_bind_int
(statement, parameter-
Index, aVariable)
int Lie une valeur entire
un paramtre substi-
tuable dune instruction
prpare.
statement un pointeur
sqlite3_stmt.
parameterIndex
lindice du paramtre
substituable dans
linstruction prpare.
aVariable un nombre
entier enregistrer dans la
base de donnes.
Tableau 7.7 : API de SQLite3 (suite)
Objet/fonction Valeur de retour Description Paramtres
iPhone Livre Page 178 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 179
Dans le code prcdent, la variable sqlite3_stmt passe a t xe au cours de lexcution de
la fonction sqlite3_prepare_v2 et contient le sqlite3_stmt qui est ensuite utilis pour
obtenir chaque lment de donnes du jeu de rsultats de la requte SQL excute. Une
suite dappels la fonction sqlite3_step dplace un curseur qui dsigne la position de la
ligne dans le jeu des rsultats. Ainsi, lorsque le jeu de rsultats est vide, ou ne contient
aucune ligne, sqlite3_step retourne non plus SQLITE_ROW mais SQLITE_DONE. Cela
permet dutiliser une instruction while pour extraire les donnes de la ligne indique par
le curseur.
while (sqlite3_step(statement) == SQLITE_ROW) {
...
}
Dans cette boucle while, plusieurs NSMutableArrays sont crs ; voir la ligne 218 du
chier SQLiteDataAccess.m et la ligne suivante. Chacun de ces tableaux reprsente une
ligne du jeu de rsultats et se nomme donc row.
NSMutableArray *row = [[NSMutableArray alloc] initWithCapacity:numResultColumns];
Pour obtenir les valeurs des diffrents champs des enregistrements du jeu de rsultats, il
faut appeler les fonctions associes au type appropri. Le Tableau 7.7 recense ces fonctions et
le code suivant montre comment les utiliser.
int type = [[[theResult columnTypes]
objectAtIndex:i] intValue];
if(type == SQLITE_INTEGER){
NSNumber *aNum = [[NSNumber alloc]
initWithInt: sqlite3_column_int(statement, i)];
[row addObject:aNum];
[aNum autorelease];
}
else if(type == SQLITE_FLOAT){
NSNumber *aFloat = [[NSNumber alloc]
initWithFloat:sqlite3_column_double(statement, i)];
[row addObject:aFloat];
[aFloat autorelease];
}
else if(type == SQLITE_TEXT){
NSString *aText = [[NSString alloc]
initWithCString:sqlite3_column_text(statement, i)
encoding:NSASCIIStringEncoding];
[row addObject:aText];
[aText autorelease];
}
else if(type == SQLITE_BLOB){
iPhone Livre Page 179 Vendredi, 30. octobre 2009 12:04 12
180 Dveloppez des applications pour liPhone
NSData *aData = [[NSData alloc]
dataWithBytes:sqlite3_column_blob(statement, i)
length:sqlite3_column_bytes(statement,i)];
[row addObject:aData];
[aData autorelease];
}
else{//SQLITE_NULL
[row addObject:@"null"];
}
Pour appeler la fonction approprie, le type du champ concern doit tre dtermin. Pour
cela, le type du champ est examin et enregistr avant lappel ; voir les lignes 199 205
dans le chier SQLiteDataAccess.m et le code suivant.
NSMutableArray *columnTypes = [[NSMutableArray alloc]
initWithCapacity:0];
for(int i = 0; i < numResultColumns; i++){
NSNumber * columnType = [NSNumber numberWithInt:
sqlite3_column_type(statement,i)];
[columnTypes addObject:columnType];
}
[theResult setColumnTypes:columnTypes];
Le type de chaque colonne est obtenu partir du jeu de rsultats de linstruction en invo-
quant la fonction sqlite3_column_type. Le pointeur sur linstruction et le numro du
champ concern sont passs la fonction, qui retourne un indicateur numrique du type de
ce champ. Voici les types reconnus :
SQLITE_INTEGER ;
SQLITE_FLOAT ;
SQLITE_BLOB ;
SQLITE_NULL ;
SQLITE_TEXT.
Les mthodes dbAccess, setData et getData retournent un pointeur sur un DataAccess-
Result. Cet objet contient les rsultats de lexcution dune instruction SQL sur une base
de donnes SQLite. Le code suivant est extrait du chier DataAccessResult.h et montre les
champs utiliss pour enregistrer les rsultats dune excution SQL.
@interface DataAccessResult: NSObject {
NSArray *fieldNames;
NSArray *columnTypes;
NSArray *results;
iPhone Livre Page 180 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 181
NSString *errorDescription;
NSInteger rowsAffected;
NSInteger insertedID;
}
@property (nonatomic, retain) NSArray *fieldNames;
@property (nonatomic, retain) NSArray *columnTypes;
@property (nonatomic, retain) NSArray *results;
@property (nonatomic, retain) NSString *errorDescription;
@property (nonatomic) NSInteger rowsAffected;
@property (nonatomic) NSInteger insertedID;
- (NSString*) JSONStringify;
@end
Le Chapitre 4 la expliqu, puisque le framework prend en charge le passage des donnes,
tous les objets DataAccessResult gnrs par des appels SQLiteDataAccess sont
inclus dans les paramtres transmis aux objets de contrle de lafchage (VCO, View
Control Object). Puisquun appel JavaScript est effectu pour obtenir ou xer les donnes
dans une base de donnes "native", les rsultats de la requte doivent tre renvoys
lapplication JavaScript. Cette opration est ralise par lobjet SendDBResultVCO.
linstar de tous les objets de commande, SendDBResultVCO offre une mthode doCom-
mand. Puisque les donnes doivent tre renvoyes au code JavaScript, elles sont converties
en une chane JSON (lignes 8 11 du code suivant). Chaque rsultat est dabord converti
en une chane JSON et ajout au tableau retVal de type NSMutableArray. Ce tableau est
ensuite converti en une chane JSON. En raison des limitations de la bibliothque JSON
dObjective-C, il est impossible de convertir les tableaux dobjets en une chane JSON en
un seul appel. La bibliothque ne parcourt pas les objets des tableaux pour effectuer les
conversions appropries. Un appel supplmentaire JSONStringify est donc ncessaire
pour chaque objet DataAccessResult.
1 + (id) doCommand:(NSArray*) parameters{
...
2 NSArray *results = [parameters subarrayWithRange:aRange];
3 int numResults = [results count];
4 NSMutableArray *retVal = [[NSMutableArray alloc] init];
5 for(int i = 0; i < numResults; i++){
6 DataAccessResult * aResult =
7 (DataAccessResult*)[results objectAtIndex:i];
8 NSString* resultString = [aResult JSONStringify];
iPhone Livre Page 181 Vendredi, 30. octobre 2009 12:04 12
182 Dveloppez des applications pour liPhone
9 [retVal addObject:resultString];
10 }
11 [retVal addObject:[parameters objectAtIndex:4]];
12
13 SBJSON *generator = [SBJSON alloc];
14 NSError *error;
15 NSString *dataString = [generator stringWithObject:retVal error:&error];
16 [generator release];
17 dataString = [dataString
18 stringByReplacingOccurrencesOfString:@"" withString:@"\\"];
19 NSString *jsString = [[NSString alloc]
20 initWithFormat:
21 @"handleRequestCompletionFromNative(%@)
22 , dataString];
23 QuickConnectViewController *controller =
24 [parameters objectAtIndex:0];
25 [controller.webView
26 stringByEvaluatingJavaScriptFromString:jsString]);
27 return nil;
28 }
Comme au Chapitre 4, o les rsultats taient convertis en une chane JSON, un appel
permet de les passer la partie JavaScript de lapplication en vue de leur traitement. Il sagit
de lappel stringByEvaluatingJavaScriptFromString vu prcdemment. Il excute la
fonction JavaScript handleRequestCompletionFromNative pour sassurer que tous les
autres BCO et VCO associs la commande dorigine soient excuts. Pour de plus
amples informations concernant ce fonctionnement, consultez le Chapitre 5.
En rsum
Le module JavaScript DataAccessObject facilite normment les interactions avec les
bases de donnes SQLite prises en charge par le moteur WebKit. Puisque ce module
accepte uniquement les types JavaScript standard, comme les chanes de caractres et les
tableaux, il est plus facile employer que les fonctions JavaScript SQLite de WebKit.
DataAccessObject est galement une faade utilise pour accder aux chiers de base de
donnes "natives" que vous pouvez livrer avec votre application. Avec des appels Java-
Script, il est possible daccder aux donnes prsentes dans la base. De cette manire,
lapplication JavaScript est une application complte qui offre les mmes fonctionnalits
que lapplication quivalente crite en Objective-C.
linstar du DataAccessObject JavaScript, la classe Objective-C SQLiteDataAccess
facilite lextraction ou lenregistrement des donnes dans des bases SQLite livres avec
iPhone Livre Page 182 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 7 Bases de donnes 183
lapplication. Puisquelle suit la mme conception que la classe JavaScript DataAccess-
Object, il est plus facile de comprendre son rle, mme sans matriser Objective-C.
Puisque tous les rsultats des requtes effectues sur les bases de donnes du moteur
WebKit ou les bases de donnes "natives" sont des objets qui contiennent des types Java-
Script standard, il est inutile de connatre les dtails internes du fonctionnement de SQLite
avec WebKit ou en natif.
DataAccessObject et SQLiteDataAccess se fondent sur les transactions pour viter que
les appels asynchrones ne perturbent les requtes. Vous pouvez effectuer plusieurs appels
concurrents la base de donnes sans vous inquiter dventuelles perturbations sur les
donnes dans la base. Le chapitre suivant explique comment raliser une enveloppe pour les
appels AJAX qui ressemble et se comporte de manire comparable DataAccessObject.
iPhone Livre Page 183 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 184 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
8
Donnes distantes
Votre application peut avoir besoin daccder des donnes qui se trouvent dans une base
de donnes distante ou qui sont fournies par des services web. Vous pourriez mme vouloir
synchroniser les donnes du tlphone avec des donnes enregistres distance.
Les applications hybrides pour liPhone facilitent la mise en uvre de ces comportements.
Puisquelles sont hybrides, elles disposent dun accs total lobjet XMLHttpRequest
depuis le code JavaScript. Ce chapitre explique comment obtenir des donnes partir dun
ux RSS et les afcher dans votre application.
Comme pour laccs aux bases de donnes examin au Chapitre 7, une enveloppe
simple demploi pour lobjet XMLHttpRequest est dcrite dans la premire section. Les
sections suivantes expliquent comment cette enveloppe a t cre et son fonctionne-
ment interne.
iPhone Livre Page 185 Vendredi, 30. octobre 2009 12:04 12
186 Dveloppez des applications pour liPhone
Section 1 : application browserAJAXAccess
Au Chapitre 7, lapplication nativeDBAccess a illustr lenregistrement et la rcupration
des donnes partir dune base de donnes SQLite sur un appareil. Ce chapitre dcrit une
application semblable qui permet dinteragir avec des services et des serveurs web pour
obtenir des donnes. La Figure 8.1 montre lapplication browserAJAXAccess en cours
dexcution.
Tous les blogs WordPress proposent un ux RSS qui fournit les dix derniers billets du blog
(voir Figure 8.2). Bien que ce ux ne semble pas proposer lensemble des billets du blog, en
ralit ce nest pas le cas. Lapplication browserAJAXAccess afche uniquement les inti-
tuls, mais il est trs facile de ltendre pour enregistrer les intituls et les billets la
manire dcrite au Chapitre 7.
Heureusement, les ux RSS se moquent du client. Un ux reoit une demande pour les
billets du blog et les envoie au format XML, quel que soit le demandeur. Puisque UIWeb-
View intgre le moteur WebKit, il peut envoyer des requtes au ux et interprter le
contenu XML reu. Pour cela, loutil utilis prend la forme de lobjet XMLHttpRequest et
la mthode employe se nomme AJAX.
Figure 8.1
Lapplication
browserAJAXAccess
afche le contenu du blog
de TetonTech.
iPhone Livre Page 186 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 187
AJAX na rien de grec
LIliade est lun des plus grands textes de tous les temps. Cette pope dHomre raconte
la guerre entres les Grecs, ou Achens, et les Troyens.
Lun des hros grecs se nomme Ajax. Il bat constamment ses adversaires et, lors dun
pisode, il sauve lui seul la otte grecque de la destruction.
linstar de la otte grecque, le dveloppement traditionnel des pages web a subi et
subit des attaques. On lui reproche dtre trop lent, trop difcile employer et pas assez
exible. Une fois encore, AJAX vient la rescousse, mais il ne sagit plus du hros grec. Ce
nouvel AJAX signie Asynchronous JavaScript and XML.
Lide derrire AJAX est simple : amliorer lexprience utilisateur en ne rechargeant pas
les pages chaque requte. la place, des donnes sont envoyes ou obtenues, et les
rsultats sont prsents en employant des techniques issues du HTML dynamique. Tout
cela peut tre ralis dans une page laide de JavaScript.
En conjuguant lobjet XMLHttpRequest et du code JavaScript simple pour manipuler une
page web, votre application hybride pour liPhone peut exploiter des donnes distantes
comme si elles taient locales. Vous obtenez alors le meilleur des deux mondes : lapplication
Figure 8.2
Le ux RSS de TetonTech
afch dans Safari.
iPhone Livre Page 187 Vendredi, 30. octobre 2009 12:04 12
188 Dveloppez des applications pour liPhone
peut sexcuter en mode autonome, sexcuter en mode rseau et synchroniser les donnes
lorsquune connexion est disponible. Le framework QuickConnectiPhone fournit une
enveloppe AJAX simple demploi : ServerAccessObject.
Section 2 : utilisation de ServerAccessObject
Lenveloppe AJAX ServerAccessObject vous permet daccder facilement des
donnes distantes sans connatre les dtails de lAPI de XMLHttpRequest. LAPI de
ServerAccessObject est quasiment identique celle de DataAccessObject examine au
Chapitre 7. Elle comprend un constructeur et deux mthodes. Le constructeur enregistre
lURL du serveur distant et congure les mthodes de lobjet. Les deux mthodes,
getData et setData, permettent ensuite dobtenir et denvoyer des donnes au serveur
distant dni dans le constructeur. Le Tableau 8.1 dcrit lAPI de ServerAccessObject.
Tableau 8.1 : API de ServerAccessObject
Attribut/mthode Valeur de retour Description Paramtres
ServerAccessObject
(URL)
ServerAcces-
Object
Cre un ServerAcces-
sObject lorsquelle est
appele avec le mot cl
new.
URL lURL du serveur
contacter.
getData(dataType,
refresh, parameter-
Sequence, HTTPHeaders)
void Cette mthode permet
dobtenir des informations
depuis un serveur distant.
La requte est de type GET.
Cette mthode est sre vis-
-vis des threads.
dataType le type des
donnes obtenir : Serve-
rAccessObject.XML ou
ServerAccessOb-
ject.TEXT.
refresh un boolen qui
indique si une mise jour
force des donnes depuis le
serveur doit tre effectue.
parameterSequence les
paramtres ajouter
lURL. Le point dinterro-
gation initial (?) nest pas
inclus.
HTTPHeaders un tableau
associatif contenant les
noms et les valeurs des en-
ttes envoyer avec la
requte.
iPhone Livre Page 188 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 189
Le chier ServerAccessObject.js, qui se trouve dans le groupe QCiPhone des modles
Dashcode et Xcode, contient lenveloppe ServerAccessObject. Il est automatiquement
inclus dans le chier index.html de lapplication par les deux modles.
La fonction getSiteDataBCF, dnie dans le chier functions.js, utilise ServerAccess-
Object. Ce chier JavaScript contient toutes les fonctions de contrle pour lapplication
browserAJAXAccess. Pour de plus amples informations concernant ces types de fonctions
et la manire de les crer, consultez le Chapitre 2.
Lobjectif de la fonction getSiteDataBCF est dobtenir les billets partir du blog de
lauteur. Ce comportement est facile mettre en uvre laide de lobjet ServerAccess-
Object, comme le montrent les lignes 2 5 du code suivant :
1 function getSiteDataBCF(parameters){
2 var site = new ServerAccessObject(
3 http://tetontech.wordpress.com/feed/);
4 site.getData(ServerAccessObject.XML,
setData(dataType,
parameterSequence,
data, HTTPHeaders)
void Cette mthode est utilise
pour modier ou crer des
informations sur un serveur
distant, ou pour passer des
types de paramtres scuri-
ss. La requte est de type
POST. Cette mthode est
sre vis--vis des threads.
dataType le type des
donnes obtenir : Serve-
rAccessObject.XML ou
ServerAccessOb-
ject.TEXT.
parameterSequence les
paramtres ajouter
lURL. Le point dinterro-
gation initial (?) nest pas
inclus.
data les donnes
inclure dans lenvoi. Il peut
sagir dune grande quantit
de caractres, dun chier,
etc.
HTTPHeaders un tableau
associatif contenant les
noms et les valeurs des en-
ttes envoyer avec la
requte.
Tableau 8.1 : API de ServerAccessObject (suite)
Attribut/mthode Valeur de retour Description Paramtres
iPhone Livre Page 189 Vendredi, 30. octobre 2009 12:04 12
190 Dveloppez des applications pour liPhone
5 ServerAccessObject.REFRESH);
6 // Puisque les appels AJAX sont asynchrones,
7 // cette BCF ne retourne aucune valeur.
8
9 }
Les lignes 2 et 3 construisent le ServerAccessObject. Il reoit lURL du ux RSS, dans
ce cas celle du blog de lauteur (http://tetontech.wordpress.com/feed). Pour accder un
autre blog WordPress, vous devez simplement remplacer cette URL.
Les lignes 4 et 5 utilisent ensuite ce nouvel objet nomm site pour obtenir les donnes.
Puisquil sagit dun ux RSS et que le serveur renvoie des donnes XML lapplication
browserAJAXAccess, on indique que les donnes sont de type XML. Le second paramtre
force une actualisation des donnes, au lieu quelles soient prises dans un cache. Ce fonc-
tionnement est indispensable si vous souhaitez garantir que les donnes reues contiennent
toutes les modications enregistres sur le serveur.
Une utilisation inconsidre de lactualisation peut conduire des effets secondaires nga-
tifs. Si lactualisation est demande alors quelle nest pas requise, le serveur et le rseau
peuvent se trouver surchargs dans le cas o lapplication devient populaire. Cest pour-
quoi il faut dterminer si les toutes dernires donnes doivent tre obtenues ou si elles
peuvent tre lgrement obsoltes.
linstar de DataAccessObject, tous les appels ServerAccessObject sont asynchrones.
Plusieurs appels peuvent tre effectus en parallle, tant quun nouveau Server-Access-
Object est cr pour chacun deux. Avec le framework QuickConnectiPhone, il est inutile
de dnir une fonction de rappel comme cela est requis lorsquon utilise AJAX. Le
framework sassure de lexcution des fonctions de contrle mtier (BCF, Business
Control Function) et des fonctions de contrle de lafchage (VCF, View Control Function)
associes la mme commande que la BCF qui invoque ServerAccessObject.
Dans le chier mappings.js, les fonctions getSiteDataBCF et displaySiteDataVCF sont
associes la commande sampleQuery (voir Chapitre 2). Autrement dit, les donnes
demandes par getSiteDataBCF sont certaines dtre passes displaySiteDataVCF par
le framework.
Le code de displaySiteDataVCF est donn ci-aprs. Le paramtre results pass cette
fonction est un tableau dobjets JavaScript, un pour chaque BCF associe la commande
sampleQuery. La mthode getData de ServerAccessObject conduit la cration dun
objet QueryResult, comme ctait le cas dans la mthode getData de DataAccess-
Object ; pour de plus amples informations concernant lobjet QueryResult, consultez le
Chapitre 7.
iPhone Livre Page 190 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 191
Aprs avoir effac les lments afchs et reprsents par la variable container dans le
code suivant, lobjet QueryResult contenant les rsultats de lappel AJAX est obtenu
(ligne 9). Puisque getSiteDataBCF est la premire BCF associe la commande sample-
Query, les rsultats gnrs par son invocation se trouvent dans le premier objet du tableau
results pass en paramtre.
Nous lavons vu au Chapitre 7, les objets QueryResult possdent un attribut nomm
data. Dans le cas des requtes XML, comme celle effectue dans getSiteDataBCF, cet
attribut contient le document XML rsultant.
Puisque ce document est comparable un document utilis habituellement avec du
contenu HTML dynamique, il est trait de manire semblable. Les mmes types de mtho-
des sont disponibles, comme getElementById et getElementsByTagName. Il est gale-
ment constitu dobjets Node, avec des relations de parent, denfants et de frres. Vous
pouvez employer toutes les mthodes et solutions classiques pour interprter les donnes.
La fonction utilitaire parseWordPressFeed, dnie dans le chier RSSUtilities.js, est
appele la ligne 9. Elle emploie la mthode standard pour obtenir un tableau en deux
dimensions, nomm entries, qui contient les billets de blog. Chaque entre du tableau
comprend la date de publication, le contenu et lintitul du billet.
1 function displaySiteDataVCF(results, parameters){
2 var container =
3 document.getElementById(queryResults);
4 // Effacer le conteneur.
5 while(container.lastChild){
6 container.removeChild(container.lastChild);
7 }
8 // Utiliser un parseur wordpress pour crer les objets des billets.
9 var entries = parseWordPressFeed(results[0].data);
10 var numEntries = entries.length;
11 // Pour chaque billet, ajouter lintitul et la date
12 // dans le <div> conteneur.
13 for (var i = numEntries-1; i >= 0; i--){
14 var entry = entries[i];
15 var publishDate = entry.date;
16 var title = entry.title;
17
18 var titleElement = document.createElement(h2);
19 titleElement.innerText = entry.title;
20 container.appendChild(titleElement);
21
22 var dateElement = document.createElement(h3);
iPhone Livre Page 191 Vendredi, 30. octobre 2009 12:04 12
192 Dveloppez des applications pour liPhone
23 dateElement.innerText = entry.date;
24 container.appendChild(dateElement);
25
26 var hardRule = document.createElement(hr);
27 container.appendChild(hardRule);
28 }
29 }
Pour chaque entre gnre par la fonction parseWordPressFeed, les lignes 13 28
crent des objets HTML Element et les insrent dans le conteneur. Lintitul et la date de
chaque billet de blog sont ainsi afchs. Une ligne est ensuite ajoute pour sparer chaque
billet afch.
Cet exemple montre comment grer les ux RSS, mais dautres types daccs sont aussi
simples, si ce nest faciles. Vous pouvez effectuer une requte de type TEXT et obtenir le
contenu HTML insrer dans linterface utilisateur de votre application. Toutefois, cette
approche est dconseille pour des questions de scurit. Vous pouvez galement effectuer
un appel de type TEXT pour obtenir des donnes au format JSON.
JSON na rien de grec, lui non plus
JSON se prononce "Jaison", comme le Jason (avec laccent anglais) avec ses Argonautes.
Il est intressant de remarquer que le long voyage de Jason et de ses compagnons avait
pour objectif de ramener la Toison dor.
JSON (JavaScript Object Notation) est utilis pour faire voyager les objets JavaScript sur de
longues distances dans les rseaux. Le code suivant montre comment crer un objet Java-
Script qui enregistre un nom et un prnom :
var unObjet = new Object();
unObjet.prenom = Paul;
unObjet.nom = Martin;
Le code suivant illustre une autre syntaxe :
var unObjet = {prenom:Paul, nom:Martin};
Lequel est correct ? Les deux ralisent la mme chose. La seconde solution est probable-
ment plus rapide, mais, lorsque les objets sont grands, la premire est plus lisible et facile
modier.
La seconde syntaxe a pour avantage de pouvoir tre passe sous forme dune chane de
caractres :
"{prenom:Paul, nom:Martin}"
iPhone Livre Page 192 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 193
Cette chane peut ensuite tre convertie en un objet en la passant la fonction JavaScript
standard eval, mais cette mthode est dangereuse. Pour une solution plus sre et simple
demploi, consultez lAnnexe A.
Est-ce une concidence si, tels les deux hros grecs, AJAX et JSON sont l pour sauver le
dveloppement de type web ? vous de dcider.
Quel que soit le type des donnes obtenir, ServerAccessObject facilite cette opration.
Il suft simplement dinstancier cet objet et dappeler getData, pour une requte de type
GET, ou setData, pour une requte de type POST. Dans tous les cas, le framework Quick-
ConnectiPhone passe les informations aux autres objets de contrle associs la
commande.
Section 3 : ServerAccessObject
La section prcdente a montr comment lutilisation de ServerAccessObject permettait
dexploiter les possibilits dAJAX et de lAPI de XMLHttpRequest sans avoir besoin de
matriser ces derniers. Cette section sintresse ces deux aspects et montre comment les
utiliser. Si vous souhaitez simplement vous servir de ServerAccessObject sans en
comprendre le fonctionnement, vous pouvez sauter cette section.
Grce ServerAccessObject, dni dans le chier ServerAccessObject.js du groupe
QCiPhone, le programmeur na pas besoin dune grande connaissance dAJAX pour en
exploiter les possibilits. Cette classe propose des mthodes et des constructeurs sembla-
bles ceux de lenveloppe JavaScript DataAccessObject dcrite au Chapitre 7. Puisquil
dispose dune API simplie, le programmeur qui nest pas familier dAJAX peut envoyer
et obtenir des donnes distantes sans passer par une longue phase dapprentissage. Si vous
connaissez lAPI de lun de ces objets daccs, vous pouvez employer lautre.
Le constructeur de ServerAccessObject est la plus simple de ses mthodes. Il enregistre
lURL du serveur distant et dnit ensuite les mthodes de lobjet. La ligne suivante,
extraite du constructeur, montre que lURL est enregistre dans lattribut URL de lobjet en
vue dune utilisation ultrieure.
this.URL = URL;
Outre cet attribut URL, auquel le programmeur naccde jamais directement, il faut galement
prendre en compte la mthode prive makeCall.
makeCall est au cur de ServerAccessObject. Elle effectue tout le travail requis par les
accs au serveur. Elle est invoque par les deux mthodes de faade getData et setData.
Le Tableau 8.2 dcrit son API et son utilisation de base.
iPhone Livre Page 193 Vendredi, 30. octobre 2009 12:04 12
194 Dveloppez des applications pour liPhone
Comme vous le verrez par la suite, lune des nombreuses solutions standard pour affecter
des mthodes des objets est employe pour ces faades. Elle consiste crer un objet de
fonction laide du constructeur function et affecter le rsultat un attribut de lobjet
courant reprsent par le mot cl this.
Les deux mthodes de faade getData et setData sont quasiment identiques. Elles pren-
nent quatre arguments et les passent, ainsi que trois autres, la mthode makeCall. Les
paramtres supplmentaires sont le premier, le cinquime et le septime dans lappel
getData et le premier, le troisime et le septime dans lappel setData. Le cinquime
paramtre de la mthode makeCall prcise les donnes qui doivent tre passes au serveur
laide dune requte de type POST. Il est videmment inutile pour la mthode getData et
est donc remplac par null.
this.getData = function(dataType, refresh,
parameterSequence, HTTPHeaders){
var passThroughParameters = generatePassThroughParameters();
this.makeCall(GET, dataType, refresh,
parameterSequence, null, HTTPHeaders, passThroughParameters);
}
this.setData = function(dataType,
parameterSequence, data, HTTPHeaders){
var passThroughParameters = generatePassThroughParameters();
this.makeCall(POST, dataType, true,
parameterSequence, data, HTTPHeaders, passThroughParameters);
}
Lappel la fonction generatePassThroughParameters assemble toutes les informations
qui permettent au framework de poursuivre le traitement des BCF et VCF associes la
BCF en utilisant ServerAccessObject. Pour de plus amples informations concernant
cette fonction qui se trouve dans le chier QCUtilities.js, consultez le Chapitre 5.
Le troisime paramtre de la mthode makeCall est un indicateur boolen qui prcise si le
cache du client, dans ce cas le UIWebView, doit tre utilis ou non. Pour la mthode
setData, la mise en cache tant videmment une mauvaise ide, la valeur de ce paramtre
est ge true de manire dsactiver le cache.
En incluant ces paramtres dans la signature de la mthode makeCall, elle peut encapsuler
efcacement lobtention et lenvoi des donnes un serveur distant. Ce principe de fonc-
tion utilitaire servant de faade est souvent employ lorsque, comme dans notre cas, une
iPhone Livre Page 194 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 195
grande partie du code de deux fonctions/mthodes ou plus est presque identique et que,
sans la faade, le code exhiberait une redondance importante.
Pour comprendre la mthode makeCall, il est ncessaire de comprendre lAPI de lobjet
JavaScript XMLHttpRequest sous-jacent. Cette API est mise en uvre par la classe UIWeb-
View utilise dans les applications hybrides et la version mobile de Safari.
Tableau 8.2 : API de makeCall
Attribut/mthode Valeur de retour Description Paramtres
makeCall(callType, data-
Type, refresh, parameter-
Sequence, data,
HTTPHeaders, passThrough-
Parameters)
void Cette mthode doit tre
considre comme pri-
ve. Elle effectue les
appels AJAX au serveur
et prend en charge les
rsultats.
callType GET ou
POST.
dataType TEXT ou XML.
refresh un boolen
qui indique si une mise
jour force des donnes
depuis le serveur doit tre
effectue.
parameterSequence
une chane qui contient
les paramtres de la
requte ajouts lURL.
data les donnes tex-
tuelles ou binaires
envoyes avec la requte.
Ce paramtre est utilis
avec les requtes POST.
HTTPHeaders un
tableau associatif conte-
nant les noms et les
valeurs des en-ttes
envoyer avec la requte.
passThroughParame-
ters un tableau des
valeurs requises par le
framework pour poursui-
vre le traitement aprs la
rception des donnes
depuis le serveur.
iPhone Livre Page 195 Vendredi, 30. octobre 2009 12:04 12
196 Dveloppez des applications pour liPhone
Le seul objet dni par cette API est XMLHttpRequest (voir Tableau 8.3).
Tableau 8.3 : API de XMLHttpRequest
Attribut/mthode Valeur de retour Description Paramtres
XMLHttpRequest() XMLHttpRe-
quest
Le constructeur de lobjet. Aucun.
abort() void Termine la requte. Aucun.
getAllResponse-
Headers()
String Cette mthode retourne une
chane qui contient les noms
et les valeurs de tous les en-
ttes de la rponse.
Aucun.
getResponseHea-
der(aHeaderName)
String Cette mthode retourne une
chane qui contient la valeur
de len-tte de nom indiqu
ou null si cet en-tte nexiste
pas.
aHeaderName le nom de
len-tte HTTP de la rponse
dont la valeur est recherche.
open(type, URL,
asynch, userName,
password)
void Ouvre et prpare une
connexion au serveur.
type une chane contenant
la valeur GET ou POST.
asynch un boolen qui pr-
cise si la requte doit tre
asynchrone. Ce paramtre doit
toujours avoir la valeur true.
userName un paramtre
facultatif qui prcise le nom
dutilisateur permettant dacc-
der au chier ou au rpertoire
indiqu dans lURL.
password un paramtre
facultatif qui prcise le mot de
passe de lutilisateur indiqu
pour accder au chier ou au
rpertoire indiqu dans lURL.
send(data) void Cette mthode associe des
donnes textuelles ou binaires
une requte. Elle est utilise
dans les requtes de type
POST, par exemple pour
lenvoi de chiers.
data les informations asso-
cies la requte.
iPhone Livre Page 196 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 197
SetRequestHea-
der(name, value)
void Une mthode qui peut red-
nir les valeurs des en-ttes
standard ou ajouter des en-
ttes personnaliss avec leur
valeur une requte.
name une chane qui repr
sente lidentiant de len-tte.
value une chane qui
contient la valeur associe au
nom.
onreadystatechange Un attribut auquel est affect
une fonction. Cette fonction
est invoque lorsque lvne-
ment onreadystatechange
est dclench, cest--dire
chaque modication de rea-
dyState.
readyState Un entier qui reprsente ltat
de la requte effectue. Voici
les valeurs possibles :
0 la mthode send na pas
t invoque.
1 La requte est en cours
denvoi au serveur.
2 La requte a t reue par
le serveur.
3 Une partie de la rponse
envoye par le serveur a t
reue.
4 Lintgralit de la rponse
envoye par le serveur a t
reue.
responseText Les donnes envoyes par le
serveur sous forme de texte,
sans les en-ttes HTTP de la
rponse.
responseXML Les donnes envoyes par le
serveur au format DOM XML.
Si les donnes ne sont pas du
XML valide, cet attribut est
null.
Tableau 8.3 : API de XMLHttpRequest (suite)
Attribut/mthode Valeur de retour Description Paramtres
iPhone Livre Page 197 Vendredi, 30. octobre 2009 12:04 12
198 Dveloppez des applications pour liPhone
De cette API, les mthodes les plus employes sont le constructeur, open et send. Le code
suivant donne un exemple simple dutilisation de ces mthodes et dautres attributs.
Il demande la page principale du projet open-source WebKit sous forme textuelle.
Deux points sont remarquer dans cet exemple. Tout dabord, lobjet request est global.
Il peut tre utilis dans la fonction handleResponse, qui est appele automatiquement par
le moteur du navigateur lorsque readyState change. Le code est ainsi plus simple, mais
cela risque de poser un problme si deux requtes sont mises en parallle.
var request = new XMLHttpRequest();
request.onreadystatechange = handleResponse;
request.open(GET,http://webkit.org/, true);
request.sent();
function handleResponse(){
if(request.readyState == 4){
if(request.status == 200){
var result = response.responseText;
// Utiliser result.
}
}
}
En raison de la porte globale de la variable request, cet exemple simple nest pas sr
vis--vis des threads. Puisque les requtes sont asynchrones, il est possible, et fort proba-
ble, que des requtes se perturbent. ServerAccessObject encapsule cette variable globale
de manire rsoudre ce problme.
status Un nombre envoy par le ser-
veur pour indiquer le succs
ou lchec dune requte. Les
plus frquents sont 404 (non
trouv) et 200 (succs). La
liste complte est disponible
ladresse http://www.w3.org/
Protocols/rfc2616/rfc2616-
sec10.html.
statusText Une chane gnre par le ser-
veur qui contient un message
correspondant au code dtat.
Tableau 8.3 : API de XMLHttpRequest (suite)
Attribut/mthode Valeur de retour Description Paramtres
iPhone Livre Page 198 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 199
Le deuxime point concerne lenvoi de la requte une URL complte. Dans un naviga-
teur, un objet XMLHttpRequest peut demander des donnes uniquement au serveur dont il
provient. Lobjet UIWebView utilis dans les applications hybrides ne souffre pas de cette
restriction. Il peut demander des donnes nimporte quel serveur car il nest pas un navi-
gateur. Cela reprsente la fois une aubaine et un au.
Les navigateurs sont restreints sur ce point pour viter les attaques XSS (cross-site scripting).
Elles peuvent se produire lorsque du JavaScript malveillant est insr dans du contenu
HTML sinon innocent demand par votre application. Puisque UIWebView nest pas un
navigateur, vous tes responsable de la protection de votre application contre ces attaques.
Par chance, le framework QuickConnectiPhone permet dassocier des fonctions de
contrle de la scurit (SCF, Security Control Function), qui sont invoques par Server-
AccessObject avant que les rsultats des requtes ne soient passs aux VCF.
La cration de ces SCF est comparable celle des VCF, et leur association se fait avec
mapCommandToSCF. La Section 4 donnera un exemple de cration et dutilisation des SCF.
LAPI de lobjet XMLHttpRequest ne permet pas de forcer une actualisation. Server-
AccessObject offre cette possibilit en utilisant lun des attributs HTTP standard de la
requte.
if(refresh){
/*
* Si le cache doit tre dsactiv et lappel au serveur impos,
* len-tte If-Modified-Since doit tre fix une date passe.
*/
http.setRequestHeader( "If-Modified-Since", "Sat, 1 Jan 2000 00:00:00 GMT" );
}
Len-tte If-Modified-Since indique au serveur quil doit envoyer les donnes si la date
de modication de llment demand est postrieure celle prcise par cet en-tte. En
xant la valeur de len-tte une date passe, nous sommes certains que les donnes dans
le cache ne sont pas utilises.
Par ailleurs, lAPI de ServerAccessObject ne permet pas lutilisateur dindiquer si la
requte doit tre synchrone ou asynchrone. Tous les appels AJAX doivent tre asynchro-
nes. De cette manire, le moteur web reste ractif et peut traiter les actions suivantes de
lutilisateur. Si les appels sont synchrones et si lutilisateur pivote liPhone, le UIWebView
afche un cran blanc. Cela se produit galement si lutilisateur dcide de faire dler la
vue pendant quune requte au serveur est en cours. Dans les deux cas, lexprience de
lutilisateur ne sera pas agrable. Lutilisation synchrone de lobjet XMLHttpRequest tant
donc une mauvaise ide, ServerAccessObject impose un traitement asynchrone de
toutes les requtes.
iPhone Livre Page 199 Vendredi, 30. octobre 2009 12:04 12
200 Dveloppez des applications pour liPhone
Contrairement lexemple simple prcdent, ServerAccessObject nutilise pas une
fonction standard pour grer les vnements onreadystatechange. la place, il sappuie
sur une fonction anonyme ; pour de plus amples informations concernant les fonctions
anonymes, consultez le Chapitre 3. La dcision dopter pour une fonction anonyme a t
prise en raison de sa capacit exister dans la porte de la fonction englobante.
Toutes les variables locales dclares dans la mthode makeCall sont galement disponi-
bles la fonction anonyme onreadystatechange. De cette manire, le problme de la
variable globale mentionne prcdemment est rsolu. En affectant la variable http le
nouvel objet XMLHttpRequestObject cr, qui sera utilis dans la mthode makeCall, il
se trouve automatiquement dans la porte au moment de lappel la fonction anonyme
onreadystatechange.
Ceux qui ne sont pas habitus la notion de fonction anonyme risquent de trouver cela
incongru. Ceux qui les manipulent dj y verront un moyen de raliser quelque chose dont
ils ntaient pas capables. Le code suivant contient lintgralit de cette fonction anonyme.
1 http.onreadystatechange = function(){
2
3 if(http.readyState == ServerAccessObject.COMPLETE){
4 // Le reprsentant standard de tous les types de requte.
5 var queryResult = new QueryResult();
6 // Les en-ttes derreurs personnaliss que vous pouvez
7 // envoyer depuis le code du serveur si vous le dcidez.
8 queryResult.errorNumber =
9 http.getResponseHeader(QC-Error-Number);
10 queryResult.errorMessage =
11 http.getResponseHeader(QC-Error-Message);
12 if(http.status!= ServerAccessObject.HTTP_OK
13 && http.status!= ServerAccessObject.HTTP_LOCAL
14 && http.status!=
15 ServerAccessObject.OSX_HTTP_File_Access){
16
17 queryResult.errorNumber = http.status;
18 queryResult.errorMessage = "Type daccs erron.";
19 }
20
21 /*
22 * Obtenir les donnes si le serveur indique que
23 * le traitement de la requte a russi ou si
24 * la requte concerne directement un fichier
25 * sur le disque du serveur.
26 * Les obtenir sous forme de texte ou en XML.
27 */
28 if(queryResult.errorNumber == null){
iPhone Livre Page 200 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 201
29 queryResult.data = http[response+dataType];
30 if(!dispatchToSCF(passThroughParameters[0],
31 queryResult.data)){
32 queryResult.errorNumber =
33 ServerAccessObject.INSECURE_DATA_RECEIVED;
34 queryResult.errorMessage =
35 "Donnes non fiables reues.";
36 }
37 }
38 /*
39 * Invoquer la prochaine fonction de contrle
40 * de la liste en passant resultData.
41 */
42 if(window.callFunc){
43 /*
44 * Lappel peut tre effectu depuis lextrieur
45 * dune fonction dispatchToBCF. Dans ce cas,
46 * il ny a pas de fonction callFunc
47 * dfinie.
48 */
49 var theResults = new Array();
50 theResults.push(queryResult);
51 theResults.push(passThroughParameters);
52 requestHandler(passThroughParameters[0],
53 passThroughParameters[2], theResults);
54 }
55 }
56
57 };
Les lignes 30 36 du code contiennent les appels aux SCF et aux VCF mentionnes prc-
demment. La ligne 30 est comparable au code du contrleur frontal dcrit au Chapitre 2.
En ralit, elle est pratiquement identique la fonction checkValidation dcrite et se
comporte de manire quivalente.
Tout comme un utilisateur peut saisir des donnes errones, un serveur peut envoyer des
donnes corrompues. linstar de checkValidation, checkSecurity est une fonction de
type contrleur dapplication. Elle invoque les SCF qui ont t associes dans le chier
mapping.js la commande qui est associe la BCF en utilisant ServerAccessObject.
Vous pouvez ainsi appliquer tous les contrles de scurit que vous souhaitez aux donnes
reues depuis un serveur et contrer plus facilement les attaques XSS.
Aprs avoir vri les donnes, elles sont ajoutes un objet QueryResult pour que
lapplication puisse poursuivre leur traitement. Cela passe par un appel la fonction
requestHandler. passThroughParameters est utilis ici car il contient la commande qui
iPhone Livre Page 201 Vendredi, 30. octobre 2009 12:04 12
202 Dveloppez des applications pour liPhone
a dclench lappel la BCF et la fonction de contrle doit tre invoque ensuite. En appe-
lant requestHandler, la mthode makeCall de ServerAccessObject garantit que toutes
les fonctions de contrle sont invoques dans lordre o elles ont t associes dans le
chier mappings.js. Puisque theResults est galement pass, il est disponible toutes les
autres fonctions de contrle. Autrement dit, vous pouvez utiliser les donnes comme bon
vous semble.
Puisque la fonction anonyme onreadystatechange comprend ces deux appels des fonc-
tions de type contrleur dapplication et puisquil sagit de la seule fonction laquelle un
serveur envoie des donnes, elle joue le rle dun contrleur frontal supplmentaire pour
lapplication. Autrement dit, en utilisant ServerAccessObject pour tous les accs des
donnes distantes, vous bnciez des avantages des communications distantes examines
au Chapitre 2 pour les applications standard.
Ce modle de double contrleur frontal apporte la scurit ncessaire aux applications,
tout en donnant la possibilit dobtenir des donnes depuis nimporte quel serveur. La
Figure 8.3 montre comment ces contrleurs frontaux protgent votre application et vos
donnes.
Figure 8.3
Les utilisateurs et les serveurs peuvent fournir des donnes errones lapplication. Le modle du double
contrleur frontal protge le code de lapplication des donnes potentiellement nfastes.
Utilisateur Serveur
h
a
n
d
l
e
R
e
q
u
e
s
t

<
c
o
n
t
r

l
e
u
r

f
r
o
n
t
a
l
>
F
o
n
c
t
i
o
n

a
n
o
n
y
m
e

o
n
r
e
a
d
y
s
t
a
t
e
c
h
a
n
g
e

<
c
o
n
t
r

l
e
u
r

f
r
o
n
t
a
l
>
Vos
ValCF
Vos
BCF
Vos
ECF
Vos
VCF
Vos
SCF
iPhone Livre Page 202 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre 8 Donnes distantes 203
Section 4 : fonctions de contrle de la scurit
Les SCF sont invoques par ServerAccessObject pour vrier la validit des donnes
obtenues depuis un serveur. Elles jouent un rle quivalant aux ValCF dcrites au Chapi-
tre 2. Elles suivent galement le mme schma que toutes les autres fonctions de contrle.
Pour quune SCF puisse tre invoque, elle doit tre associe une commande. Par exem-
ple, lapplication peut imposer lutilisateur douvrir une session an quelle renvoie les
donnes JSON en cas de succs. Voici un exemple de ce type dassociation :
mapCommandToSCF(login, checkForFunctions);
Cela signie que vous devez galement disposer dune fonction checkForFunctions qui
peut tre appele par checkSecurity.
Puisque la bibliothque json2 est disponible dans le chier json2.js du groupe QCiPhone,
cette fonction est simple crire.
function checkForFunctions(data){
if(data == JSON.stringify(JSON.parse(data){
return true;
}
return false;
}
Au cours de lanalyse des donnes, la mthode JSON.parse ajoute des caractres suppl-
mentaires dans la chane si elle rencontre des dclarations ou des appels de fonctions. Cela
permet de faire chouer ces dnitions ou ces appels de fonctions, apportant ainsi une
scurit supplmentaire contre les attaques XSS.
Vos vrications peuvent exploiter cela en reconvertissant le nouvel objet JavaScript cr
en une chane et en la comparant celle dorigine. Si la comparaison choue, lapplication
sait que les donnes obtenues du serveur contiennent du code malveillant.
Le texte JSON qui vous est envoy ne peut donc pas contenir les dnitions ou des appels
de fonctions. Ce point est trs intressant. En effet, si ce ntait pas le cas, vous ne pourriez
jamais dire si les fonctions JavaScript contenues dans les donnes JSON sont de votre fait
ou si du code malveillant a t insr au cours dune attaque XSS.
iPhone Livre Page 203 Vendredi, 30. octobre 2009 12:04 12
204 Dveloppez des applications pour liPhone
En rsum
ServerAccessObject constitue une solution facile et scurise pour obtenir des donnes
partir de sources distantes dans une application hybride. Cette classe apporte une API
simple demploi, comparable celle de DataAccess, qui rduit votre temps dapprentissage.
Grce aux SCF, le code obtenu peut tre vri soigneusement avant que vous ne le dclariez
valide.
ServerAccessObject peut obtenir des donnes distantes et les enregistrer par linterm-
diaire de DataAccessObject en vue de leur utilisation ultrieure, ou les utiliser directe-
ment comme dans le cas de lapplication browserAJAXAccess. Il ouvre galement des
possibilits de synchronisation entre les donnes enregistres sur la machine locale et
celles prsentes sur une machine distante.
ServerAccessObject permet de crer du code qui peut signaler automatiquement un
serveur web lchec du code de lapplication. Vous pouvez galement lutiliser pour rali-
ser des mesures partir de votre application pour liPhone et les envoyer un serveur de
manire rendre lapplication plus rapide et plus simple utiliser.
Grce ServerAccessObject, toutes ces possibilits sont dsormais facilement utilisables
dans votre application hybride installe sur liPhone.
iPhone Livre Page 204 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
A
Introduction JSON
JSON (JavaScript Object Notation) apporte des possibilits trs intressantes. Il
permet de convertir des objets et des tableaux JavaScript en chanes de caractres, qui
peuvent ensuite tre transmises sur le rseau ou enregistres dans une base de donnes.
Ces chanes peuvent ultrieurement tre reconverties en objets ou tableaux sur un autre
ordinateur ou aprs avoir t extraites dune base de donnes. Cette capacit srialiser
et charger des objets et des tableaux JavaScript ouvre de nombreuses possibilits.
Cette annexe prsente une API pour la bibliothque JavaScript JSON et fournit quelques
exemples de son utilisation.
Section 1 : les fondamentaux
La transmission dinformations dun systme un autre a toujours reprsent un
problme. Cela devient particulirement vident dans le dveloppement dapplications
web o un serveur peut tre crit dans nimporte quel langage et sexcuter sur diffrents
types dordinateurs. XML a t lun des premiers formats indpendants de lappareil, du
systme dexploitation et du langage propos pour rsoudre ce problme dchange et
iPhone Livre Page 205 Vendredi, 30. octobre 2009 12:04 12
206 Dveloppez des applications pour liPhone
certaines de ses utilisations se sont rvles intressantes. Lutilisation du format XML
pour transfrer des donnes peut sembler exagre, en particulier pour les petits lments
dinformation gnralement envoys avec AJAX. Si vous souhaitez envoyer uniquement
un petit tableau de nombres ou une mappe de cls-valeurs, XML se rvle un peu verbeux.
Ce point a t rsolu, non en inventant une nouvelle technologie, mais en employant une
fonctionnalit des langages interprts.
Tous les principaux langages interprts faiblement typs disposent dune fonctionnalit
dvaluation, par exemple une fonction eval, qui permet dexcuter des chanes de carac-
tres comme sil sagissait dun code source. Cette possibilit est puissante, mais dange-
reuse. En cas de mauvaise utilisation, elle peut totalement ouvrir lapplication aux pirates
et aux abus. Par ailleurs, tous les principaux langages interprts faiblement typs ont la
possibilit de dnir des tableaux et des objets sans passer par un mot cl dinstanciation
de type new.
Si vous examinez des exemples JavaScript, vous verrez comment crer un tableau. Voici
comment procder dans une approche oriente objet :
var tableau = new Array();
tableau.push(5);
tableau.push(13);
tableau.push(Bonjour);
La solution suivante nest pas oriente objet :
var tableau = [5,13,Bonjour];
Ces deux exemples crent des tableaux parfaitement identiques. Le deuxime est intres-
sant pour notre prsentation de JSON. Conjugu aux possibilits JavaScript dvaluation
dune chane comme du code, il permet de bncier de JSON.
Le code suivant cre une chane de caractres qui correspond la manire dont un
programmeur utiliserait la seconde mthode de cration dun tableau. Il sagit non pas du
tableau en soi, mais dune description de ce que doit tre ce tableau.
var uneChaine = "[5,13, Bonjour]";
// valuer la chane.
var tableau = eval(uneChaine);
iPhone Livre Page 206 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Annexe A Introduction JSON 207
La dernire ligne parse la chane en un code source JavaScript, interprte ce contenu
JavaScript et lexcute. Dans cet exemple simple, la chane se trouve dans la mme
application que lappel la fonction eval et, par consquent, cette utilisation montre
peu dintrt. En revanche, si la chane provient de la partie Objective-C dune applica-
tion QuickConnectiPhone ou, plus classiquement, dun serveur, lappel eval a plus
de sens.
La cration dobjets est comparable. Dans lapproche oriente objet suivante, un objet est
cr et des attributs lui sont ensuite ajouts :
var objet = new Object();
objet.largeur = 5;
objet.hauteur = 13;
objet.message = Bonjour;
Voici la version non oriente objet :
var objet = {"largeur":5,"hauteur":13,"message":"Bonjour"};
Le code suivant est de type JSON :
var uneChaine = {"largeur":5,"hauteur":13,"message":"Bonjour"};
// valuer la chane.
var objet = eval(uneChaine);
Bien que cette procdure soit au cur de JSON, sa mise en uvre par le programmeur
prsente un danger. Par exemple, si la chane a t envoye depuis le code JavaScript vers
le ct Objective-C de QuickConnectiPhone et si elle contient des instructions complexes,
elle peut potentiellement effacer le disque dur.
Des bibliothques JSON ont t dveloppes pour prendre en charge les problmes de
scurit. Celle que nous utilisons dans la partie JavaScript se nomme Json2 et est propo-
se par le chier json2.js. Json2 est lun des parseurs JSON les plus utiliss en JavaS-
cript. Puisque des donnes sont rgulirement changes avec la partie Objective-C des
applications fondes sur QuickConnectiPhone, vous devez comprendre lAPI de cette
bibliothque.
iPhone Livre Page 207 Vendredi, 30. octobre 2009 12:04 12
208 Dveloppez des applications pour liPhone
Section 2 : une API JavaScript pour JSON
LAPI de Json2, dcrite au Tableau A.1, est simple. Elle est constitue de deux fonctions :
une premire pour convertir un objet ou un tableau en une chane de caractres et une
seconde pour convertir des chanes de caractres en objets.
La premire fonction se nomme stringify. Elle prend plusieurs arguments, mais dans le
cas de QuickConnectiPhone seul le premier est obligatoire. Il sagit de lobjet ou du
tableau convertir en chane de caractres. En voici un exemple :
var chaineJSON = JSON.stringify(objet);
Tableau A.1 : LAPI de Json2
Fonction Paramtres
JSON.stringify(entity, replacer,
space, linebreak)
Paramtre obligatoire :
entity lobjet, le tableau ou le type primitif JavaScript
convertir.
Paramtres facultatifs :
replacer une fonction ou un tableau qui permet de rednir la
gnration par dfaut des chanes de caractres pour les valeurs
associes aux cls des entits JavaScript.
space un nombre ou un caractre, comme \t ou &nbsp, uti-
lis pour indenter les entits JavaScript qui sont les valeurs enre-
gistres avec des cls dans dautres entits.
linebreak un ou plusieurs caractres qui remplacent le carac-
tre \n par dfaut, comme \r\n ou <br/>.
JSON.parse(string, reviver) Paramtre obligatoire :
string la chane JSON convertir en un objet ou un tableau de
JavaScript.
Paramtre facultatif :
reviver une fonction qui met en uvre un comportement
inverse celui de la fonction replacer utilise avec la mthode
stringify.
iPhone Livre Page 208 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Annexe A Introduction JSON 209
La conversion dune chane en objet est tout aussi simple :
var objet = JSON.parse(uneChaine);
Les tableaux sont pris en charge de la mme manire.
Un exemple complet dutilisation de Json2 pour convertir en chanes et parser des objets se
trouve dans le rpertoire Examples/JSON de QuickConnectiPhone (object_JSON_ exam-
ple.html). La Figure A.1 illustre la conversion dun objet en une chane, qui est ensuite
reconvertie en un objet, ainsi que lafchage de lattribut size de lobjet.
Le rpertoire Examples/JSON contient galement lexemple array_JSON_example.html,
qui illustre lutilisation de Json2 avec des tableaux (voir Figure A.2).
Notez que ces deux exemples utilisent les termes standard dans lindustrie pour les fonc-
tions de srialisation et de reconstruction : stringify et parse.
La bibliothque Json2 permet galement de passer des types primitifs, comme des nombres.
Les chanes de caractres sont aussi prises en charge. Ce nest pas le cas de toutes les biblio-
thques JSON dans tous les langages. La Figure A.3 illustre ces possibilits.
Grce la bibliothque Json2, vous pouvez convertir en chane de caractres nimporte
quel type de donnes, et le reconstruire ensuite. La bibliothque JSON de la partie Objec-
tive-C prend galement en charge les types primitifs et les chanes de caractres.
Figure A.1
Convertir un objet en
chane de caractres et
inversement.
iPhone Livre Page 209 Vendredi, 30. octobre 2009 12:04 12
210 Dveloppez des applications pour liPhone
Figure A.2
Convertir un tableau en
chane de caractres et
inversement.
Figure A.3
Convertir des types primi-
tifs et des chanes de
caractres en chanes de
caractres et inversement.
iPhone Livre Page 210 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Annexe A Introduction JSON 211
En rsum
JSON constitue une bonne solution pour changer des informations. Il est indpendant de
lappareil, du systme dexploitation et du langage. Il existe des parseurs open-source
gratuits dans tous les langages couramment utiliss, dont certains, comme PHP, les intgrent
directement.
La bibliothque Json2 fournie avec QuickConnectiPhone est facile utiliser et vous
permet dchanger des donnes avec le ct Objective-C dune application hybride.
iPhone Livre Page 211 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 212 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
B
Plan de dveloppement
pour QuickConnectFamily
Puisque le dveloppement de QuickConnectiPhone en est ses dbuts, les amliorations
sont frquentes. Il est donc important de suivre de prs les mises jour. Le Tableau B.1
recense les fonctionnalits disponibles au 3 octobre 2009. Vous pouvez consulter la feuille
de route du projet ladresse http://quickconnect.pbworks.com/Porting-Roadmap.
Oui indique que la fonctionnalit est disponible. En cours signie que la fonctionnalit est
en cours de dveloppement. Prvu signale que la fonctionnalit est envisageable mais que
son dveloppement nest pas commenc. Impossible sapplique une fonctionnalit qui ne
peut pas tre mise en uvre sur lappareil. Les cases qui contiennent un tiret signalent un
travail qui nest pas ralis au moment de lcriture de ces lignes.
Bien que le dveloppement soit prvu pour Windows et Windows Mobile, rien
nest encore commenc et le Tableau B.1 omet donc ces systmes.
In
f
o
iPhone Livre Page 213 Vendredi, 30. octobre 2009 12:04 12
214 Dveloppez des applications pour liPhone
T
a
b
l
e
a
u

B
.
1

:

F
e
u
i
l
l
e

d
e

r
o
u
t
e

d
e

Q
u
i
c
k
C
o
n
n
e
c
t
F
a
m
i
l
y

a
u

3

o
c
t
o
b
r
e

2
0
0
9

i
P
h
o
n
e
A
n
d
r
o
i
d
M
a
c
L
i
n
u
x
S
y
m
b
i
a
n
W
i
n
d
o
w
s
W
i
n
d
o
w
s

M
o
b
i
l
e
P
a
l
m

W
e
b
O
S
1
G

o
l
o
c
a
l
i
s
a
t
i
o
n
O
u
i
O
u
i
I
m
p
o
s
s
i
b
l
e
I
m
p
o
s
s
i
b
l
e
P
r

v
u
I
m
p
o
s
s
i
b
l
e

P
r

v
u
A
c
c

r
o
m

t
r
e
O
u
i
O
u
i
P
r

v
u
I
m
p
o
s
s
i
b
l
e
P
r

v
u
I
m
p
o
s
s
i
b
l
e

P
r

v
u
V
i
b
r
e
u
r
O
u
i
O
u
i
I
m
p
o
s
s
i
b
l
e
I
m
p
o
s
s
i
b
l
e

I
m
p
o
s
s
i
b
l
e

s
e
a
u

a
d

h
o
c
O
u
i
E
n

c
o
u
r
s
O
u
i
P
r

v
u
P
r

v
u
P
r

v
u
P
r

v
u

E
n
v
e
l
o
p
p
e

J
a
v
a
S
c
r
i
p
t

p
o
u
r

l
e
s

b
a
s
e
s

d
e

d
o
n
n

e
s

(
S
Q
L
i
t
e
)
O
u
i
I
m
p
o
s
s
i
b
l
e
O
u
i
O
u
i
E
n

c
o
u
r
s
P
r

v
u
P
r

v
u
P
r

v
u
E
n
v
e
l
o
p
p
e

p
o
u
r

l
e
s

b
a
s
e
s

d
e

d
o
n
n

e
s

n
a
t
i
v
e
s

i
n
s
t
a
l
l

e
s

(
S
Q
L
i
t
e
)
O
u
i
O
u
i
O
u
i
O
u
i
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s

E
n
v
e
l
o
p
p
e

A
J
A
X
O
u
i
I
m
p
o
s
s
i
b
l
e
2
O
u
i
O
u
i
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s

B
i
b
l
i
o
t
h

q
u
e

d
e

g
l
i
s
s
e
r
-
d

p
o
s
e
r
O
u
i
I
m
p
o
s
s
i
b
l
e
3
O
u
i

P
r

v
u
R

s
e
a
u

p
a
r

c

b
l
e

d
e

s
y
n
c
h
r
o
n
i
s
a
t
i
o
n
P
r

v
u

P
r

v
u

A
c
c

a
p
p
a
r
e
i
l

p
h
o
t
o
E
n

c
o
u
r
s

O
u
i

o
l
o
c
a
l
i
s
a
t
i
o
n

d

i
m
a
g
e
s
P
r

v
u

P
r

v
u

S
o
n
s

s
y
s
t

m
e

(
l
e
c
t
u
r
e
)
O
u
i
O
u
i
O
u
i
P
r

v
u
P
r

v
u
E
n

c
o
u
r
s
E
n

c
o
u
r
s
P
r

v
u
E
n
r
e
g
i
s
t
r
e
m
e
n
t
/
l
e
c
t
u
r
e

d
e

c
h
i
e
r
s

a
u
d
i
o
O
u
i
O
u
i
O
u
i
P
r

v
u

E
n

c
o
u
r
s

P
r

v
u
E
n
r
e
g
i
s
t
r
e
m
e
n
t
/
l
e
c
t
u
r
e

d
e

c
h
i
e
r
s

v
i
d

o
E
n

c
o
u
r
s
I
m
p
o
s
s
i
b
l
e
O
u
i
P
r

v
u

E
n

c
o
u
r
s

P
r

v
u
S

l
e
c
t
e
u
r
s

d
e

d
a
t
e
/
h
e
u
r
e

n
a
t
i
f
s
O
u
i
I
m
p
o
s
s
i
b
l
e
I
m
p
o
s
s
i
b
l
e
I
m
p
o
s
s
i
b
l
e
I
m
p
o
s
s
i
b
l
e
P
r

v
u
P
r

v
u
P
r

v
u
C
a
r
t
e
s

G
o
o
g
l
e

e
m
b
a
r
q
u

e
s
O
u
i
E
n

c
o
u
r
s
O
u
i
P
r

v
u
P
r

v
u
P
r

v
u
P
r

v
u
P
r

v
u
iPhone Livre Page 214 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Annexe B Plan de dveloppement pour QuickConnectFamily 215
B
i
b
l
i
o
t
h

q
u
e

p
o
u
r

t
a
b
l
e
a
u
x

e
t

g
r
a
p
h
i
q
u
e
s
O
u
i
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s
P
r

v
u
I
n
f
o
r
m
a
t
i
o
n
s

s
u
r

l

a
p
p
a
r
e
i
l
O
u
i
O
u
i
E
n

c
o
u
r
s
E
n

c
o
u
r
s
E
n

c
o
u
r
s

P
r

v
u
R

s
e
a
u

P
2
P

B
l
u
e
t
o
o
t
h
E
n

c
o
u
r
s

D
i
f
f
u
s
i
o
n

a
u
d
i
o
E
n

c
o
u
r
s

B
a
l
i
s
e
s

a
u
d
i
o
/
v
i
d

o

d
e

H
T
M
L
5
O
u
i

O
u
i
O
u
i

A
P
I

p
o
u
r

l
e
s

c
o
n
t
a
c
t
s
E
n

c
o
u
r
s

(
b

t
a
)

N
o
t
i

c
a
t
i
o
n
E
n

c
o
u
r
s

(
b

t
a
)

L
e
c
t
e
u
r

d
e

b
i
b
l
i
o
t
h

q
u
e

a
u
d
i
o
E
n

c
o
u
r
s

l
e
c
t
e
u
r

a
u
d
i
o

n
a
t
i
f
E
n

c
o
u
r
s
O
u
i

D
i
s
c
u
s
s
i
o
n

v
o
c
a
l
e

d
e
p
u
i
s

u
n
e

a
p
p
l
i
c
a
t
i
o
n
E
n

c
o
u
r
s

C
o
u
r
r
i
e
r

l
e
c
t
r
o
n
i
q
u
e

d
e
p
u
i
s

u
n
e

a
p
p
l
i
c
a
t
i
o
n
E
n

c
o
u
r
s

t
e
c
t
i
o
n

d
e

s
e
c
o
u
s
s
e
E
n

c
o
u
r
s

(
b

t
a
)

C
o
p
i
e
r
-
c
o
l
l
e
r
O
u
i

O
u
i

1
.
C
e
t
t
e

v
e
r
s
i
o
n

n
e

p
e
u
t

p
a
s

t
r
e

f
o
u
r
n
i
e

t
a
n
t

q
u
e

l
e

S
D
K

d
e

W
e
b
O
S

n
e

f
a
i
t

p
l
u
s

l

o
b
j
e
t

d

u
n

a
c
c
o
r
d

d
e

n
o
n
-
d
i
v
u
l
g
a
t
i
o
n
.
2
.
G
o
o
g
l
e

n

i
n
c
l
u
t

p
a
s

l

o
b
j
e
t

X
M
L
H
t
t
p
R
e
q
u
e
s
t

d
a
n
s

s
o
n

o
b
j
e
t

W
e
b
V
i
e
w
.

I
l

e
x
i
s
t
e

u
n
e

s
o
l
u
t
i
o
n
,

m
a
i
s

e
l
l
e

s
e

r

l
e

t
r

s

l
e
n
t
e
.
3
.
G
o
o
g
l
e

n

i
n
c
l
u
t

p
a
s

l
e
s

t
r
a
n
s
i
t
i
o
n
s

e
t

l
e
s

a
n
i
m
a
t
i
o
n
s

C
S
S

n

c
e
s
s
a
i
r
e
s


l
a

m
i
s
e

e
n

u
v
r
e

d
e

c
e
t
t
e

f
o
n
c
t
i
o
n
n
a
l
i
t

.

L

u
t
i
l
i
s
a
t
i
o
n

d
e

J
a
v
a
S
c
r
i
p
t

p
o
u
r

l
e

g
l
i
s
s
e
r
-
d

p
o
s
e
r

e
s
t

u
n
e

s
o
l
u
t
i
o
n

t
r
o
p

l
e
n
t
e
.
T
a
b
l
e
a
u

B
.
1

:

F
e
u
i
l
l
e

d
e

r
o
u
t
e

d
e

Q
u
i
c
k
C
o
n
n
e
c
t
F
a
m
i
l
y

a
u

3

o
c
t
o
b
r
e

2
0
0
9

(
s
u
i
t
e
)
i
P
h
o
n
e
A
n
d
r
o
i
d
M
a
c
L
i
n
u
x
S
y
m
b
i
a
n
W
i
n
d
o
w
s
W
i
n
d
o
w
s

M
o
b
i
l
e
P
a
l
m

W
e
b
O
S
1
iPhone Livre Page 215 Vendredi, 30. octobre 2009 12:04 12
216 Dveloppez des applications pour liPhone
Dnitions des termes employs au Tableau B.1 :
Golocalisation. Obtenir les coordonnes de localisation GPS.
Acclromtre. Obtenir les changements dorientation en x, y et z.
Vibreur. Dclencher le vibreur de lappareil.
Rseau ad hoc. Rechercher et communiquer avec les autres appareils du voisinage qui
excutent la mme application.
Enveloppe JavaScript pour les bases de donnes (SQLite). Utiliser les bases de
donnes HTML 5 intgres.
Enveloppe pour les bases de donnes natives installes (SQLite). Utiliser les bases de
donnes SQLite livres avec une application.
Enveloppe AJAX. Une bibliothque AJAX simple demploi pour obtenir des donnes
distantes.
Bibliothque de glisser-dposer. Une bibliothque simple demploi pour que lutilisateur
puisse dplacer, faire pivoter et redimensionner des lments lcran.
Rseau par cble de synchronisation. Accder des donnes et en transfrer avec une
machine de bureau laide du cble de synchronisation.
Accs lappareil photo. Prendre et enregistrer des photos.
Golocalisation dimages. Accder aux informations de golocalisation ajoutes aux
photos prises avec lappareil.
Sons systme (lecture). Jouer des sons brefs (dune dure infrieure 5 secondes).
Enregistrement/lecture de chiers audio. Enregistrer un chier audio en utilisant
lappareil et jouer ces chiers ou les chiers audio livrs avec lapplication.
Enregistrement/lecture de chiers vido. Enregistrer un chier vido en utilisant
lappareil et jouer ces chiers avec lapplication.
Slecteurs de date/heure natifs. Afcher et utiliser les slecteurs crits en Objective-C
la place des slecteurs JavaScript limits.
Cartes Google embarques. Ajouter des cartes Google personnalises dans une appli-
cation la place des cartes standard ou de lafchage de lapplication de cartographie.
Bibliothque pour tableaux et graphiques. Une bibliothque simple demploi permettant
dafcher des graphiques en segments, en barres, en secteurs et autres.
Informations sur lappareil. Obtenir les caractristiques de lappareil.
iPhone Livre Page 216 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Annexe B Plan de dveloppement pour QuickConnectFamily 217
Rseau P2P Bluetooth. tablir un rseau de pair pair en utilisant la connectivit
Bluetooth.
Diffusion audio. Accder des chiers audio en streaming.
Balises audio/vido de HTML 5. Prendre en charge les nouvelles balises de HTML 5.
API pour les contacts. Accder aux informations disponibles dans lapplication de
gestion des contacts.
Notication. Envoyer des notications.
Lecteur de bibliothque audio. Exploiter une bibliothque de chiers audio.
Slecteur audio natif. Afcher et utiliser les slecteurs crits en Objective-C.
Discussion vocale depuis une application. Dmarrer une conversation vocale sans quitter
lapplication.
Courrier lectronique depuis une application. Accder la messagerie lectronique
sans quitter lapplication.
Dtection de secousse. Dtecter si lutilisateur secoue lappareil.
Copier-coller. Prise en charge de cette fonctionnalit.
iPhone Livre Page 217 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 218 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
C
Plan de dveloppement
pour PhoneGap
Puisque le dveloppement de PhoneGap en est ses dbuts, les amliorations sont
frquentes. Il est donc important de suivre de prs les mises jour. Le Tableau C.1 vient du
wiki PhoneGap. Il recense les fonctionnalits disponibles et prvues, telles quindiques
par les dveloppeurs de ce framework. Vous pouvez consulter la feuille de route du projet
ladresse http://phonegap.pbworks.com/Roadmap.
Oui indique que les fonctions JavaScript existent dans PhoneGap au 3 octobre 2009.
Lauteur nest pas en mesure de commenter la disponibilit pour la plate-forme Black-
berry. En cours signie que lquipe PhoneGap travaille sur la fonctionnalit. Les cases
qui contiennent un tiret signalent un travail qui nest pas ralis et qui nexiste pas encore.
Impossible concerne les fonctionnalits que les dveloppeurs considrent indisponibles
sur lappareil.
iPhone Livre Page 219 Vendredi, 30. octobre 2009 12:04 12
220 Dveloppez des applications pour liPhone
Bien que le dveloppement soit prvu pour Windows Mobile, rien nest encore
commenc et le Tableau C.1 omet donc ce systme.
Tableau C.1 : Feuille de route de PhoneGap au 3 octobre 2009
iPhone Android
Blackberry (OS
4.5)
Symbian
Golocalisation Oui Oui Oui Oui
Acclromtre Oui Oui Disponible dans
OS 4.7
En cours
Appareil photo Oui En cours En cours
Vibreur Oui Oui Oui Oui
Hors ligne (chiers
locaux)
En cours Oui En cours
API pour les contacts Oui Oui Oui
Enveloppe SQLite Oui Impossible
API XMPP En cours
E/S du systme de chiers En cours En cours
Geste/toucher multiple Oui
API SMS En cours
API de tlphonie En cours En cours En cours
Copier-coller Oui
Sons (lecture) Oui En cours En cours
Sons (enregistrement) En cours
Bluetooth
Connexion Wi-Fi ad hoc
Cartes Oui En cours En cours
Changement dorientation Oui En cours
Disponibilit rseau Oui En cours
Magntomtre Oui (modle
3GS)
En cours
In
f
o
iPhone Livre Page 220 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Chapitre C Plan de dveloppement pour PhoneGap 221
Dnitions des termes employs au Tableau C.1 :
Golocalisation. Obtenir les coordonnes de localisation GPS.
Acclromtre. Obtenir les changements dorientation en x, y et z.
Appareil photo. Prendre et enregistrer des photos.
Vibreur. Dclencher le vibreur de lappareil.
Hors ligne (chiers locaux). Fichiers HTML, CSS et JavaScript installs avec lappli-
cation (non sur un serveur web).
API pour les contacts. Accder aux informations disponibles dans lapplication de
gestion des contacts.
API XMPP. Messageries de type Jabber.
E/S du systme de chiers. Lire et crire des chiers textuels ou binaires.
Geste/toucher multiple. Utiliser un ou plusieurs doigts pour la saisie de donnes
complexes.
API SMS. Messagerie instantane.
API de tlphonie. Passer des appels tlphoniques.
Copier-coller. Dupliquer des donnes saisies.
Sons (lecture). Jouer des chiers audio.
Sons (enregistrement). Enregistrer des chiers audio laide de lappareil.
Bluetooth. Utiliser la connectivit Bluetooth avec dautres appareils.
Connexion Wi-Fi ad hoc. Rechercher et communiquer avec dautres appareils.
Cartes. Utiliser des cartes Google.
Changement dorientation. Dtecter le passage en modes portrait et paysage.
Disponibilit rseau. Dtecter si lappareil a accs au rseau.
Magntomtre. Obtenir les informations de la boussole intgre.
iPhone Livre Page 221 Vendredi, 30. octobre 2009 12:04 12
iPhone Livre Page 222 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Index

Symboles
__(double soulign) 117
__gap, variable 117
__gap_device_model, variable
117
A
abort, mthode 196
accel, commande 94
Acclromtres
PhoneGap 130
QuickConnectiPhone 94
Accs
aux bases de donnes
BrowserDBAccess,
application dexemple
151-153
dans WebKit 161-172
natives 172-182
SQLite avec WebView
153-158
SQLite natives 158-161
vue densemble 151
aux donnes distantes
BrowserAJAXAccess,
application dexemple
186-188
fonction de contrle de
la scurit 203
ServerAccessObject 188
Voir ServerAccessOb-
ject
vue densemble 185
Actualisation de laffichage
visible 36
add, fonction 38
Affichage
cartes gographiques 133-
138
slecteurs 97
AJAX 187
Anonymes, fonctions 161
Appareil, activation
en JavaScript 92-98, 115-
122
en Objective-C 98-106,
122-130
applicationDidFinishLaunching,
mthode 22, 24
Applications
dexemple
BrowserAJAXAccess
186-188
BrowserDBAccess
151-153
dimmersion 69-70
hybrides
bote dalerte et 8
dfinition 1
non fondes sur les listes
64-68
Approvisionnement 16
Arrter la lecture des
enregistrements 95
Asynchrone, dfinition 49
AudioServicesPlaySystem-
Sound, fonction 124
iPhone Livre Page 223 Vendredi, 30. octobre 2009 12:04 12
224 Dveloppez des applications pour liPhone
B
Balayement 59
Base de donnes
BrowserDBAccess,
application dexemple
151-153
de WebKit 161-172
Database, objet 163-165
dbAccess, mthode 163
exemple de code 170
generatePassThroughPa-
rameters, fonction 163
getData, mthode 162
passThroughParameters,
tableau 163
setData, mthode 162
SQLError, objet 169
SQLResultSet, objet 167
SQLResultSetRowList,
objet 167-169
SQLTransaction, objet
165
natives 172-182
API SQLite3 175
getDeviceData,
mthode 173
getNativeData, mthode
173
makeCall, fonction 174
SendDBResultVCO,
objet 181
setNativeData, mthode
173
SQLite avec WebView
153-158
SQLite natives 158-161
terminologie 152
vue densemble 151
BCF (Business Control
Function) 36, 38, 42, 50
Bote dalerte
applications hybrides et 8
PhoneGap 119
BrowserAJAXAccess,
application dexemple 186-
188
BrowserDBAccess,
application dexemple 151-
153
C
calculateSolutionsBCF,
fonction 39
callFunc, fonction 52
Cartes gographiques
afficher dans une appli-
cation JavaScript
QuickConnect 133-138
module de QuickConnect
138-149
zoom 144-148
Chanes de caractres
convertir des objets/
tableaux en 208
convertir en objets 209
Champs de base de donnes
152
changeView, fonction 63
checkNumbersValCF,
fonction 41
checkSecurity, fonction 201
Classes
DataAccessObject
bases de donnes de
WebKit 161-172
bases de donnes
SQLite avec WebView
153-158
bases de donnes
SQLite natives 158-161
mthodes 154
GlassAppDelegate 23
QuickConnectViewControl
-ler 22
singletons 107
SQLiteDataAccess 172-182
Cls
trangres 153
primaires 153
code, attribut (SQLError) 169
Comportements standard 59
Contenu web, embarquer
avec PhoneGap 29-30
avec QuickConnectiPhone
25-29
Contrleurs
daffichage 49-53
dapplication 41
derreur 53-54
mtier 49-53
Conversion
chanes de caractres en
objets 208, 209
objets en chanes de
caractres 208
Copie de fichiers 13
Cube, transition 67
D
Dashcode 8
modle
QuickConnectiPhone 8-
10
rpertoires 14
transitions 66
iPhone Livre Page 224 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Index 225
DataAccessObject, classe
base de donnes de WebKit
161-172
Database, objet 163-165
dbAccess, mthode 163
exemple de code 170
generatePassThroughPa-
rameters, fonction 163
getData, mthode 162
passThroughParameters,
tableau 163
setData, mthode 162
SQLError, objet 169
SQLResultSet, objet 167
SQLResultSetRowList,
objet 167-169
SQLTransaction, objet
165
base de donnes SQLite
avec WebView 153-158
natives 158-161
mthodes 154
DataAccessObject, mthode
154
DataAccessObject.js, fichier
153
Database, objet 163-165
dbAccess, mthode 163, 169
Dfiler, transition 66
Dlgus 19
deleteScoreBCF, fonction 158
Dplacement 87
Dveloppement, outils
PhoneGap
feuille de route 219
ressources en ligne 5
vue densemble 1-2
QuickConnectiPhone
feuille de route 213
ressources en ligne 5
vue densemble 1-2
Device.exec, fonction 119
Device.init, mthode 117
Device.Location.init, mthode
120
Device.vibrate, mthode 119
Diapositive, transition 67
didAccelerate, mthode 130
didUpdateToLocation,
mthode 130
dispatchToBCF, fonction 49, 50
dispatchToECF, fonction 54
dispatchToValCF, fonction 45
dispatchToVCF, fonction 53
displayScoresVCF, fonction
156, 160
displaySiteDataVCF, fonction
190, 191, 192
displaySolutionVCF, fonction
39
Dissolution, transition 66
doCommand, mthode 104,
110, 111, 139, 181
DollarStash, application
dexemple 69
done, mthode 75
Donnes distantes, accder
BrowserAJAXAccess,
application dexemple
186-188
fonctions de contrle de la
scurit (SCF) 203
ServerAccessObject, classe
188-193
displaySiteDataVCF,
fonction 190, 191, 192
getData, mthode 188,
193
getSiteDataBCF,
fonction 189
makeCall, mthode
193, 195, 196
onreadystatechange,
fonction anonyme 200,
201
ServerAccessObject,
mthode 188
setData, mthode 189,
193
XMLHttpRequest, objet
196, 198
vue densemble 185
Donnes, obtenir 36
Double soulign (__) 117
Double-touchers, avec les
cartes gographiques 143
dragAndGesture, application
dexemple 79
E
ECF (Error Control Function)
39, 43, 53-54
changer, transition 67
Embarquer
contenu web
PhoneGap 29-30
QuickConnectiPhone
25-29
Google Maps 133-138
Enregistrements
audio
arrter 95
lire en JavaScript 95
de base de donnes 152
entryECF, fonction 39
eval
fonction 42
type 206
executeSQL, mthode 166,
170
iPhone Livre Page 225 Vendredi, 30. octobre 2009 12:04 12
226 Dveloppez des applications pour liPhone
F
Faire pivoter, transition 67
Feuilles de route
PhoneGap 219
QuickConnectiPhone 213
Fichiers
copier 13
DataAccessObject.js 153
ServerAccessObject.js 189
Fonctionnalits dune
application, tapes de
cration 54
Fonctions
anonymes 161
checkSecurity 201
dassociation, API 40
de contrle de laffichage
(VCF) 36
displayScoresVCF 156,
160
de contrle de la scurit
(SCF) 203
de contrle de la validation
(ValCF) 36
de contrle des erreurs
(ECF) 39
de contrle mtier (BCF)
36
de contrle, modularit 36
de rotation 77
deleteScoreBCF 156-158
dispatchToVCF 53
displayScoresVCF 156,
160
displaySiteDataVCF 190,
191, 192
generatePassThroughPara-
meters 163
getSiteDataBCF 189
makeCall 174
onreadystatechange 200,
201
parse 208, 209
requestHandler 201
stringify 208
Fondu, transition 67
Frameworks 34
FrontController, API 37
G
generatePassThroughParame-
ters, fonction 163
Gestes 59, 76
getAllResponseHeaders,
mthode 196
getData methodgetData,
mthode 154, 193
getData, mthode 156, 162,
188
getDeviceData, mthode 173
getGPSLocation, fonction 96
getInstance, mthode 108
getNativeData, mthode 155,
160, 173
getResponseHeader, mthode
196
getSiteDataBCF, fonction 189
GlassAppDelegate, classe 23
Glisser-dposer 59
API 78
modules 78-89
sautillement des lments
73
goForward, mthode 64
Google Maps, dans une
application JavaScript
QuickConnect 133-138
goSub, fonction 64
gotAcceleration, fonction 121
GPS
JavaScript 96
Objective-C 103, 104, 105
PhoneGap 120, 126
QuickConnectiPhone 96,
121
Groupes Xcode 14
Guide de linterface utilisateur
57
H
handleRequest, fonction 37,
44
handleRequestCompletionFrom-
Native, mthode 182
HIG (Human Interface Guide)
57-61
HistoryExample, application
dexemple 61
Hybrides, applications, bote
dalerte et 8
I
Imagerie mdicale,
applications 69
Immersion, applications 69-
70
InfoWindow, classe 138, 149
initWithContentsOfFile,
mthode 127
initWithFrame:andLocations,
mthode 138
insertID, attribut
(SQLResultSet) 167
Instanciation dobjets en
Objective-C 16
Instructions prpares 157
iPhone Livre Page 226 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Index 227
Interfaces
applications fondes sur les
vues 63, 64
interfaces fondes sur les
listes 61-64
transformations CSS 71-78
vues 64
Interrupteurs 60
isDraggable, attribut 81
item, mthode 168
J
JavaScript
activation de lappareil 92-
98, 115-122
modularit 33-34
exemple QuickConnect
35-43
scroll, fonction 141
JavaScript Object Notation
Voir JSON
JSON (JavaScript Object
Notation) 95, 192
activation de lappareil en
Objective-C 101
API Json2 208-209
vue densemble 205-207
Json2, API 208-209
JSONStringify, mthode 181
L
Lecture
enregistrements audio en
JavaScript 95
sons systme en Objective-
C 102
length, attribut
(SQLResultSetRowList)
168
Listes
applications non fondes
sur 64-68
interfaces fondes sur 61-64
loadView, mthode 25
M
makeCall, fonction 92, 93, 174
makeCall, mthode 193, 195,
196
makeChangeable, fonction 79,
81
makeDraggable, fonction 78,
80
Mandant-dlgu, relations 19
Mandants 19
Mandataires 19
mapCommands, mthode 102
mapCommandToCO,
mthode 112
MapView, classe 138
math, commande 37, 39
message, attribut (SQLError)
169
Mthodes
abort 196
applicationDidFinishLaun-
ching 22
DataAccessObject 154
dbAccess 163, 169
de rappel 127
doCommand 181
executeSQL 166, 170
getAllResponseHeaders
196
getData 154, 156, 162,
188, 193
getDeviceData 173
getNativeData 155, 160,
173
getResponseHeader 196
handleRequestCompletion
FromNative 182
item 168
JSONStringify 181
makeCall 193, 195, 196
open 196
openDatabase 164
readyState 197
responseText 197
responseXML 197
send 197
ServerAccessObject 188
setData 154, 155, 156,
162, 189, 193
setNativeData 155, 173
SetRequestHeader 197
sqlite3_bind_blob 177
sqlite3_bind_double 178
sqlite3_bind_int 178
sqlite3_changes 176
sqlite3_close 175
sqlite3_column_blob 177
sqlite3_column_bytes 177
sqlite3_column_count 175
sqlite3_column_double
176
sqlite3_column_int 176
sqlite3_column_name 175
sqlite3_column_text 177
sqlite3_column_type 176
sqlite3_errmsg 175
sqlite3_finalize 177
sqlite3_open 175
sqlite3_prepare_v2 175
sqlite3_step 176
sqlite3_stmt 175
iPhone Livre Page 227 Vendredi, 30. octobre 2009 12:04 12
228 Dveloppez des applications pour liPhone
Mthodes (suite)
stringByEvaluatingJavaScr
iptFromString 182
transaction 164, 170
XMLHttpRequest 196
Modles
QuickConnectiPhone
pour Dashcode 8-10
pour Xcode 12-16
Modularit
fonctions de contrle 36
JavaScript 33-34
exemple QuickConnect
35-43
implmenter dans
QuickConnectiPhone
44-48
Modules
dfinition 34
glisser-dposer 78-89
redimensionnement 78-89
rotation 78-89
moveX:andY, mthode 147
N
Natives, bases de donnes
accder 172-182
API SQLite3 175
getDeviceData,
mthode 173
getNativeData, mthode
173
makeCall, fonction 174
SendDBResultVCO,
objet 181
setNativeData, mthode
173
SQLite, accder 158-161
Navigateur, partie 61-64
NSLog, fonction 111
O
Objective-C 16-19
activation de lappareil 98-
106, 122-130
architecture de
QuickConnectiPhone
107-113
instancier des objets 16
module de cartographie de
QuickConnect 138-149
slecteurs 106
structure dune application
PhoneGap 23-25
QuickConnectiPhone
19-22
Objets
convertir des chanes de
caractres en 209
convertir en chanes de
caractres 208
crer 207
Database 163-165
instancier en Objective-C
16
SendDBResultVCO 181
ServerAccessObject 188
SQLError 169
sqlite3 175
SQLResultSet 167
SQLResultSetRowList
167-169
SQLTransaction 165
XMLHttpRequest 196, 198
oldScale, attribut 82
ongesturechange, vnement 86
onreadystatechange
attribut 197
fonction anonyme 200, 201
ontouchchange, gestionnaire
74
ontouchend, gestionnaire 75
open, mthode 196
openDatabase, mthode 164
P
parse, fonction 208, 209
passThroughParameters,
tableau 163
PhoneGap 8, 9
acclromtres 130
activation de lappareil
en JavaScript 115-122
en Objective-C 122-130
API JavaScript 118
bote dalerte 119
embarquer du contenu web
29-30
feuille de route 219
GPS 120, 126
ressources en ligne 5
signaler un
dysfonctionnement
lutilisateur 119
son systme 128
structure Objective-C dune
application 23-25
vibreur 117, 124
vue densemble 1-2
Pin, classe 138, 142
Pincement 59
play, commande 93
playSound
commande 93
mthode pour PhoneGap
122
playTweetSound, fonction
121
Pointeurs 17
prepareDrag, fonction 82
iPhone Livre Page 228 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Index 229
Prpares, instructions 157
prepareGesture, fonction 86
Protocoles 20
Q
QCCommandObject, classe
110
QuickConnectFamily,
programme dinstallation 8
QuickConnectiPhone
acclromtres 94
activation de lappareil
en JavaScript 92-98
en Objective-C 98-106
afficher des cartes 133-138
embarquer du contenu web
25-29
feuille de route 213
GPS 96, 121
implmentation Objective-
C 107-113
implmenter une
conception modulaire
44-48
modles
Dashcode 8-10
Xcode 12
modularit de JavaScript
35-43
module de cartographie
138-149
ressources en ligne 5
structure Objective-C dune
application 19-22
vibreur 93, 100
vue densemble 1-2
QuickConnectViewController,
classe 22
R
rangeOfString, mthode 125
readyState, mthode 197
Rcursivit, dfinition 52
Redimensionnement, module
78-89
Rpertoires de Dashcode 14
requestHandler, fonction 201
responseText, mthode 197
responseXML, mthode 197
Ressources en lignes
PhoneGap 5
QuickConnectiPhone 5
retVal, tableau 181
Rotation, module 78-89
Rotation, transition 67
rows, attribut (SQLResultSet)
167
rowsAffected, attribut
(SQLResultSet) 167
S
Saisie textuelle de lutilisateur
59
Saut des lments, lors du
glisser-dposer 73
SCF (Security Control
Function) 203
scroll, fonction 141
Slecteurs
afficher 97
Objective-C 106
send, mthode 197
SendDBResultVCO, objet 181
sendloc, commande 105
ServerAccessObject, classe
188-193, 193-202
displaySiteDataVCF,
fonction 190, 191, 192
getData, mthode 188, 193
getSiteDataBCF, fonction
189
makeCall, mthode 193,
195, 196
onreadystatechange,
fonction anonyme 200,
201
ServerAccessObject,
mthode 188
setData, mthode 189, 193
XMLHttpRequest, objet
196, 198
ServerAccessObject, mthode
188
ServerAccessObject.js, fichier
189
setData, mthode 154, 155,
156, 162, 189, 193
setMapLatLngFrameWithDes
cription, mthode 148
setNativeData, mthode 155,
173
SetRequestHeader, mthode
197
setStartLocation, fonction 73
shouldStartLoadWithRequest,
fonction 99
showDateSelector, fonction
97
showMap, fonction 136
showPickResults, commande
97
Singletons, classes 107
singleTouch, message 143
Sons systme
JavaScript 93
jouer en Objective-C 102
PhoneGap 128
Sous-prsentations, liste 62
SQLError, objet 169
iPhone Livre Page 229 Vendredi, 30. octobre 2009 12:04 12
230 Dveloppez des applications pour liPhone
SQLite, bases de donnes
avec WebView 153-158
de WebKit 161-172
Database, objet 163-165
dbAccess, mthode 163
exemple de code 170
generatePassThroughPa-
rameters, fonction 163
getData, mthode 162
passThroughParameters,
tableau 163
setData, mthode 162
SQLError, objet 169
SQLResultSet, objet
167
SQLResultSetRowList,
objet 167-169
SQLTransaction, objet
165
natives 158-161
SQLite3, API 175
sqlite3, objet 175
sqlite3_bind_blob, mthode
177
sqlite3_bind_double, mthode
178
sqlite3_bind_int, mthode 178
sqlite3_changes, mthode 176
sqlite3_close, mthode 175
sqlite3_column_blob,
mthode 177
sqlite3_column_bytes,
mthode 177
sqlite3_column_count,
mthode 175
sqlite3_column_double,
mthode 176
sqlite3_column_int, mthode
176
sqlite3_column_name,
mthode 175
sqlite3_column_text, mthode
177
sqlite3_column_type,
mthode 176
sqlite3_errmsg, mthode 175
sqlite3_finalize, mthode 177
sqlite3_open, mthode 175
sqlite3_prepare_v2, mthode
175
sqlite3_step, mthode 176
sqlite3_stmt, mthode 175
SQLiteDataAccess, classe
172-182
SQLResultSet, objet 167
SQLResultSetRowList, objet
167-169
SQLTransaction, objet 165
status, messages
(XMLHttpRequest) 198
statusText, chane
(XMLHttpRequest) 197,
198
stringByEvaluatingJavaScript
FromString, mthode 182
stringify, fonction 208
Synchrone, dfinition 49
T
Tableaux
convertir en chanes 208
crer 206
passThroughParameters
163
retVal 181
Tables 152
Tlchargement de Xcode 5
Touch, classe 72
Touchers
vnements de 72
images pour indiquer 64
simples, avec les cartes
gographiques 143
simples, avec les cartes
gographiques 143
zones 58
touchesBegan, mthode 144
touchesMoved:withEvent,
mthode 140, 147
transaction, mthode 164, 170
Transformations CSS
personnalises, crer 71-78
Transitions 66
translate, fonction 75
Type eval 206
U
UIWebView
API 27
classe 25, 26
Utilisateur
crans visibles, actualiser
36
saisie, valider 36
V
ValCF (Validation Control
Function) 36, 38, 43, 48
Valider la saisie de
lutilisateur 36
VCF (View Control Function)
36, 38, 43, 49, 53
Vibreur
PhoneGap 117, 124
QuickConnectiPhone 93,
100
iPhone Livre Page 230 Vendredi, 30. octobre 2009 12:04 12
Openmirrors.com
Index 231
Vues 64
applications fondes sur
63, 64
secondaires 27
W
WebKit 71
bases de donnes 161-172
Database, objet 163-165
dbAccess, mthode 163
exemple de code 170
generatePassThroughPa-
rameters, fonction 163
getData, mthode 162
passThroughParameters,
tableau 163
SQLError, objet 169
SQLResultSet, objet 167
SQLResultSetRowList,
objet 167-169
SQLTransaction, objet
165
webkitTransform, attribut 71,
74
webMapView, attribut 139
WebView, base de donnes
SQLite 153-158
webView:shouldStartLoadWith-
Request:navigationType,
mthode 124
webViewDidStartLoad,
mthode 122
X
Xcode
groupes 14
modles
QuickConnect 12-16
tlcharger 5
XMLHttpRequest, mthode
196
XMLHttpRequest, objet 196,
198
Z
Zoom, cartes gographiques
144-148
iPhone Livre Page 231 Vendredi, 30. octobre 2009 12:04 12
Dvelopper avec Dashcode et Xcode
Modularit JavaScript
Interfaces utilisateur
GPS, acclromtre et autres fonctions
natives avec QuickConnectiPhone
GPS, acclromtre et autres fonctions
natives avec PhoneGap
Cartes Google
Bases de donnes
Donnes distantes
Introduction JSON
Plan de dveloppement pour
QuickConnectFamily
Plan de dveloppement pour PhoneGap
Dcouvrez la manire la plus simple et la plus rapide
de dvelopper des applications iPhone !
Pour crer des applications iPhone, inutile de matriser
lObjective-C : vous pouvez recourir aux technologies
et aux outils du Web que vous utilisez dj
JavaScript, HTML et CSS. Cet ouvrage vous explique
comment combiner les frameworks QuickConnect et
PhoneGap avec le kit de dveloppement dApple
pour crer des applications scurises de grande
qualit destination des iPhone.
Lauteur y dtaille le processus de dveloppement,
de la cration de superbes interfaces utilisateur
la compilation, au dploiement et lexcution
des applications. Il prsente des techniques et des
exemples de code conus pour rationnaliser le d-
veloppement, supprimer la complexit, optimiser les
performances et exploiter toutes les possibilits de
liPhone, de son acclromtre et son GPS sa base
de donnes intgre.
Grce cet ouvrage, les dveloppeurs web pourront
rapidement programmer pour liPhone en exploitant
les outils quils connaissent dj.
Les codes sources des exemples sont
tlchargeables sur le site www.pearson.fr.
Niveau : Intermdiaire
Catgorie : Dveloppement mobile
ISBN : 978-2-7440-4096-2
Dveloppez des applications pour
avec HTML,
CSS et
JavaScript iPhone
propos de lauteur
Lee S. Barney, expert en dveloppement dapplications
mobiles et web, est le crateur du framework
Quickconnect, qui permet de dvelopper des applications
en JavaScript pour liPhone.
Pearson Education France
47 bis, rue des Vinaigriers 75010 Paris
Tl. : 01 72 74 90 00
Fax : 01 42 05 22 17
www.pearson.fr
Openmirrors.com