Polytech Marseille Informatique Développement mobile - TP 2 Stéphane Ayache, Nicolas Baudru Objectifs Illustrer le mécanisme de la délégation au travers d exemples Utiliser un service web, ici le service de Geocoding de google Manipuler des chaînes de caractères Parser un fichier xml Délégation : mise en oeuvre dans Xcode La délégation est un design pattern qui permet la communication entre deux objets A et B. Lorsque un événement intercepté par A se produit, l objet A peut envoyer un message de délégation à B, et ainsi déléguer le traitement de l évenement à l objet B. On dit que B est le délégué de A. Plusieurs ingrédients sont donc nécessaires pour que la délégation puisse avoir lieu : il faut signaler à A qui est son délégué et quelles méthodes peuvent être déléguées. L ensemble des ces méthodes forment le protocole de délégation. il faut que B se conforme au protocole de délégation, et donc implémente les méthodes déléguées. Nous allons voir comment le mécanisme de délégation s implémente en Objective C. Créez un nouveau projet dans Xcode de type Single View, puis renseignez les champs demandés (nom de l application et organisation). Ajouter au storyboard un objet UITextField, créez une variable adressetextfield dans le controleur et liez la à l objet UITextField de la vue. Compilez. Dans le simulateur, cliquez sur le TextField. Le clavier apparait car un composant de saisie vient de prendre le focus. Comme beaucoup d autres composants graphiques du framework UIKit, un UITextField délègue les traitements, consécutifs à l interaction avec l utilisateur, à un autre objet : très souvent le contrôleur qui s occupe de la vue dans laquelle se trouve le composant graphique.
Dans notre cas, il s agit donc bien de la classe ViewController qui sera le délégué de adressetextfield. Puisque le controleur sera le délégué d un textfield, il doit se conformer au protocole de délégation correspondant, ici, à UITextFieldDelegate. Ajoutez ce protocole au contrôleur, dans la déclaration de la classe ViewController : //entrechevronssetrouvelalistedesprotocolesàimplémenter @interfaceviewcontroller:uiviewcontroller<uitextfielddelegate> Recherchez dans la documentation les méthodes qui peuvent être déléguées. Pour établir l association entre adressetextfield et le controleur, ajoutez à la fin de la méthode viewdidload du contrôleur : //LedéléguédutextFieldestlecontrôleurlui-même adressetextfield.delegate=self; L opération consistant à associer un objet à un délégué peut aussi se faire via le StoryBoard : glissé/déposé depuis le composant (ie: UITextField) vers le rond blanc sur fond jaune qui désigne le controleur. Il reste à implémenter les méthodes du protocole qui nous interessent. Par exemple, dans le fichier ViewController.m ajoutez les méthodes : //MéthodeappeléejusteavantqueletextFielddevienneactif -(BOOL)textFieldShouldBeginEditing:(UITextField*)textField{ NSLog(@"textFieldShouldBeginEditing"); //LefonddutextFielddevientjaunelorsdesonédition textfield.backgroundcolor=[uicoloryellowcolor]; returnyes; //Lemessage"Editionencours"estaffichédanslaconsole -(void)textfielddidbeginediting:(uitextfield*)textfield{ NSLog(@"textFieldDidBeginEditing"); //MéthodeappeléejusteavantqueletextFielddevienneinactif -(BOOL)textFieldShouldEndEditing:(UITextField*)textField{ NSLog(@"textFieldShouldEndEditing"); //LefonddutextFielddevientblanclorsdesonédition textfield.backgroundcolor=[uicolorwhitecolor]; returnyes;
//MéthodeappeléelorsqueletextFielddevientinactif -(void)textfielddidendediting:(uitextfield*)textfield{ NSLog(@"textFieldDidEndEditing"); La fonction NSLog(@ texte ) affiche texte dans la console. Une autre fonction du protocole UITextFieldDelegate qui nous intéresse consiste à récupérer l évènement d appui sur le bouton Entrée du clavier. Cet évènement peut s interpréter comme la validation et la fin de la saisie ; ou comme un besoin de passer à la ligne. La méthode déléguée suivante est appelée : -(BOOL)textFieldShouldReturn:(UITextField*)textField { //IndiquequeletextFieldlachelefocus->leclavierdisparait [textfieldresignfirstresponder]; NSLog(@ %@,textfield.text); returnyes; Remarque : dans les méthodes déléguées ci dessus, l argument textfield est un pointeur vers l objet UITextField qui a déclenché l appel à cette méthode. Dans notre cas, il s agit de adressetextfield. Compilez et vérifiez le bon fonctionnement du programme. Travail à réaliser Nous allons maintenant réaliser une application de localisation d adresse, basée sur le service de Geocoding de Google. Cette application intérogera le service google afin de récupérer les coordonnées d une adresse, et affichera sur une carte la position de celle ci à l aide de ses coordonnées. Commencez par tester le service de Geocoding : tapez dans le navigateur web Firefox l'adresse suivante, et observez le résultat. La première occurence des balises <lat> et <lng> correspondent aux coordonnées que nous cherchons. https://maps.googleapis.com/maps/api/geocode/xml?address=castellane,marseille&sensor=true
Mise en place de la vue Ajoutez à la vue les éléments graphiques suivants : un UITextField pour saisir une adresse, un UILabel, un UISwitch pour accorder/empêcher la mise à jour de la position sur la carte, un MKMapView qui affiche l adresse entrée dans le UITextField. Construction de la requête URL et obtention des coordonnées géographiques Récuperez la chaine de caractères saisie dans adressetextfield. A l aide de la méthode de classe stringwithformat, construisez et stockez la requête vers le service Google dans une variable query (de type NSString). La méthode de classe stringwithcontentsofurl s occupe d établir la connexion et télécharge le contenu directement dans un NSString. L argument de type NSURL se construit
directement à partir d un NSString (l objet query dans notre cas). Stockez le résultat de l appel à stringwithcontentsofurl dans une variable xmlcontent de type NSString. Rappelez vous que les coordonnées qui nous intéressent se trouvent dans la première occurrence des balises <lat> et <lng>. Nous présentons ici deux façons de les récupérer : - via les méthodes de NSString Très simple, utilisez les méthodes rangeofstring et substringwithrange pour extraire les coordonnées. Remarquez que NSRange est une structure C avec deux attributs : location et length. Affichez les coordonnées dans le UILabel. - via un NSXMLParser Nous allons ici instancier un objet de la classe NSXMLParser pour récupérer le contenu des balises <lat> et <lng>. Après l allocation, cet objet sera initialisé par la méthode initwithcontentofurl. La classe NSXMLParser utilise aussi le mécanisme de délégation. C est au délégué de définir le traitement à réaliser lorsqu une balise ouvrante, une balise fermante, ou du contenu sont découverts par le parseur : NSXMLParser implémente le modèle évènementiel SAX. Recherchez sur la documentation les différentes méthodes déléguées par NSXMLParser. Implémentez le délégué du NSXMLParser, ainsi que les méthodes du délégué, dans la classe ViewController. Commencez par modifier la déclaration de ViewController : @interfaceviewcontroller:uiviewcontroller<uitextfielddelegate, NSXMLParserDelegate> Affichez les coordonnées dans le label. Affichage de la position sur une carte Pour pouvoir manipuler un objet MKMapView, il est nécessaire d ajouter les frameworks CoreLocation et MapKit au projet. Pour cela, dans XCode rendez vous, sur l espace de configuration du projet (dans le panneau de gauche, appuyez sur l icone bleu en haut de la liste des fichiers). La liste des frameworks liés au projet se trouve dans la section Link Binary
With Libraries de l onglet Build Phases. Trouvé? Alors appuyez sur le signe + pour ajouter les frameworks. Insérez les imports suivants dans le ViewControler.h: #import<corelocation/corelocation.h> #import<mapkit/mapkit.h> Nous allons maintenant centrer la carte sur les coordonnées géographiques correspondant à l adresse recherchée. Pour ce faire, vous devez avoir préalablement déclaré une variable de type MKMapView et l avoir liée sur le StoryBoard. Pour modifier programatiquement les coordonnées du centre de la carte, nous devons appeler la méthode setregion:animated de l objet MKMapView. L argument region est de type MKCoordinateRegion (une structure C). Vous pouvez la créer avec la fonction MKCoordinateRegionMakeWithDistance : Le premier argument est une structure de type CLLocationCoordinate2D. Créez la à l aide de la fonction C CLLocationCoordinate2DMake, et renseignez les attributs latitude et longitude. Les deux arguments suivants correspondent à l étendue (en mètres) de la région à afficher. Pour finir, modifiez votre programme pour que l initialisation et l affichage de la carte s effectue uniquement lorsque le switch est sur on. Travail optionnel Utilisez les méthodes déléguées de MKMapView afin de réagir aux événements effectués sur la carte.