Polytech Marseille Informatique Développement mobile - TP 3. Stéphane Ayache, Nicolas Baudru



Documents pareils
Manipulation 4 : Application de «Change».

Programmation MacOSX / ios

Cette application développée en C# va récupérer un certain nombre d informations en ligne fournies par la ville de Paris :

Développez vos applications pour. iphone, ipod Touch, ipad

Optimiser pour les appareils mobiles

Le langage C. Séance n 4

Premiers Pas en Programmation Objet : les Classes et les Objets

TP2 : Client d une BDD SqlServer

Algorithmique et Programmation, IMA

Bases Java - Eclipse / Netbeans

WINDEV MOBILE. ios SMARTPHONE SUPPORT: IOS, ANDROID, WINDOWS PHONE 8.

Création d une SIGNATURE ANIMÉE avec PHOTOFILTRE 7

Sauf mention contraire, le contenu de cet ouvrage est publié sous la licence : Creative Commons BY-NC-SA 2.0 La copie de cet ouvrage est autorisée

Langage et Concepts de ProgrammationOrientée-Objet 1 / 40

La base de données XML exist. A. Belaïd

HTML. Google Maps. Approfondir. 3 :HIKONB=^UZ^Z]:?k@l@g@h@a"; Codez une fois, déployez sur Android, ios, Kindle... Smartphones. Matériel.

SOMMAIRE 1 INTRODUCTION 3 2 CONTACTER VOTRE SUPPORT 3 3 ESPACE DE GESTION DES CARTES 4 4 CONFIGURER UNE CARTE 5

TD3: tableaux avancées, première classe et chaînes

Éléments d informatique Cours 3 La programmation structurée en langage C L instruction de contrôle if

CTIconnect PRO. Guide Rapide

Plan du cours. Historique du langage Nouveautés de Java 7

TD/TP 1 Introduction au SDK d Android

Le MSMQ. Version 1.0. Pierre-Franck Chauvet

MANUEL UTILISATEUR. Application 4trip

À la découverte du SDK de l iphone et de l ipad

Manuel de l administrateur

Java Licence Professionnelle CISII,

Programmation en Java IUT GEII (MC-II1) 1

Gérer les règles de prix catalogue sur Magento

COURS WINDEV NUMERO 3

TP1 : Initiation à Java et Eclipse

DA MOTA Anthony - Comparaison de technologies : PhoneGap VS Cordova

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

EIP 2012 Projet Livepad. Documentation technique 1.5

Travaux dirigés n 10

Cours intensif Java. 1er cours: de C à Java. Enrica DUCHI LIAFA, Paris 7. Septembre Enrica.Duchi@liafa.jussieu.fr

SPECIFICATIONS TECHNIQUES : Gestion des Médicaments et des commandes de médicaments

Développement mobile MIDP 2.0 Mobile 3D Graphics API (M3G) JSR 184. Frédéric BERTIN

TP Blender n 2 : Importation d un modèle SketchUp et animation

I. Introduction aux fonctions : les fonctions standards

Procédure pas à pas de découverte de l offre. Service Cloud Cloudwatt

Utiliser un tableau de données

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

ContactForm et ContactFormLight - Gestionnaires de formulaire pour Prestashop Edité par ARETMIC S.A.

Programmer en JAVA. par Tama

Java Licence Professionnelle CISII, Cours 2 : Classes et Objets

geek Soyez le de l été! PHP :HIKONB=^UZ^Z]:?k@b@g@p@a"; Découvrez Chrome, Firefox, IE, Safari Enquête écoles Diplômes : quel prix

Chapitre 4 : Guide de Mouvement et Masque

PROJET 1 : BASE DE DONNÉES REPARTIES

Animation numérique. de territoire. Créer son site Internet avec un outil gratuit. Mardi 4 novembre Cédric ARNAULT OT Lourdes

Réalisation de cartes vectorielles avec Word

Utilisation d objets : String et ArrayList

BONNE NOUVELLE, À PARTIR DE DEMAIN 15 AOÛT 2014, l inscription en ligne sera disponible à partir du site de l ARO.

Installation et prise en main

Introduction à la Programmation Parallèle: MPI

Introduction à la programmation Travaux pratiques: séance d introduction INFO0201-1

Atelier Le gestionnaire de fichier

Studio. HERITIER Emmanuelle PERSYN Elodie. SCHMUTZ Amandine SCHWEITZER Guillaume

Corrigés des premiers exercices sur les classes

Corrigé des exercices sur les références

Un ordonnanceur stupide

Introduction au langage C

VOS PREMIERS PAS AVEC TRACENPOCHE

Développement d un logiciel de messagerie instantanée avec Dotnet (version simplifiée)

Conception des systèmes répartis

SHOPCAISSE NOTICE D UTILISATION. ShopCaisse est une solution d encaissement disponible sur ipad.

Manuel d'utilisation du site Deptinfo (Mise en route)

Documentation Liste des changements apportés

1 CRÉER UN TABLEAU. IADE Outils et Méthodes de gestion de l information

Comment paramétrer correctement son compte Facebook pour pouvoir protéger un maximum ses données et sa vie privée.

Formation Certifiante Scrum Master

MANUEL D INSTALLATION. du module Chronopost pour. version 1.0.5

Programmation Web. Madalina Croitoru IUT Montpellier

Créer une base de données vidéo sans programmation (avec Drupal)

Séminaire Partenaires Esri France 7-8 juin Paris Les API ArcGIS pour les smartphones

Création d un service web avec NetBeans 5.5 et SJAS 9


CONTACT EXPRESS 2011 ASPIRATEUR D S


Freeway 7. Nouvelles fonctionnalités

Plateforme PAYZEN. Intégration du module de paiement pour la plateforme Magento version 1.3.x.x. Paiement en plusieurs fois. Version 1.

Langage Java. Classe de première SI

JADE : Java Agent DEvelopment framework. Laboratoire IBISC & Départ. GEII Université & IUT d Evry nadia.abchiche@ibisc.univ-evry.

Version 7.1_5.1. Release Notes

TP1 - Prise en main de l environnement Unix.

Les différentes étapes à suivre pour la création d un feuillet

Outils pour la pratique

Le Logiciel de Facturation ultra simplifié spécial Auto-Entrepreneur

Flex. Lire les données de manière contrôlée. Programmation Flex 4 Aurélien VANNIEUWENHUYZE

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Chapitre I Notions de base et outils de travail

Initiation à la Programmation en Logique avec SISCtus Prolog

Traitement de texte : Quelques rappels de quelques notions de base

Introduction à l algorithmique et à la programmation M1102 CM n 3

Guide de l'utilisateur

Les possibilités de paramétrage réseau des logiciels de virtualisation sont les suivantes quant à la connexion réseau :

Documentation Analyse SEM

Guide d utilisation de PL7 Pro Récupérer ou transférer un programme

Transcription:

Polytech Marseille Informatique Développement mobile - TP 3 Stéphane Ayache, Nicolas Baudru Objectifs Illustrer la programmation par blocs S amuser avec la géolocalisation Découverte de Grand Central Dispatch Déployer les applications sur des terminaux ios Blocs : mise en oeuvre avec Objective-C La notion de bloc a été introduite par Apple depuis ios5 en extension aux langages C, C++ et Obj C pour simplifier l écriture et la lisibilité des programmes. Ils sont similaires aux fonctions C standard, mais en plus de code exécutable, ils peuvent également contenir des variables et utiliser ou modifier des variables partagées. Un bloc peut maintenir un ensemble d'états (données) qu'il peut utiliser pour modifier son comportement lorsqu'il est exécuté. Les blocs sont particulièrement utiles en tant que callbacks et remplacent ainsi la délégation pour certaines classes dans le SDK. En Objective C, les blocs sont considérés comme des objets. Ils peuvent être définis à l intérieur d autres méthodes, être affectés à une variable, être passés en arguments de méthodes ou peuvent être stockés dans des collections (NSArray, NSDictionary). Nous introduisons ici la syntaxe et la terminologie nécessaires à l utilisation des blocs.

Le signe ^ sert à la déclaration d une variable de bloc et à démarrer une expression de bloc. Le code suivant est un premier exemple de déclaration et utilisation d un bloc : int multiplier = 7 ; int (^myblock)( int ) = ^( int num) { return num * multiplier; }; // prints "21" NSLog ( @"%d", myblock( 3 )); N hésitez par à vous rendre sur la documentation en ligne, le guide de programmation par blocs est très instructif. https://developer.apple.com/library/ios/documentation/cocoa/conceptual/programmingwitho bjectivec/workingwithblocks/workingwithblocks.html Un premier bloc Dans le TP précédent, nous avions utilisé le service de Geocoding de Google à des fins pédagogiques : nous avons ainsi vu comment intérroger un service web avec la méthode stringwithcontentsofurl et comment traiter la réponse avec NSXMLParser. Le SDK ios permet aussi le geocoding, et de façon bien plus simple que nous l avons vu! Le code suivant montre comment parvenir au même résultat en cinq lignes : CLGeocoder *geocoder=[[ CLGeocoder alloc ] init ]; [geocoder geocodeaddressstring : @"Castellane,Marseille" completionhandler :^( NSArray *placemarks, NSError *error) { CLPlacemark *pl=[placemarks objectatindex : 0 ]; MKCoordinateRegion region= MKCoordinateRegionMakeWithDistance (pl. location. coordinate, 100, 100 ); [ mapview setregion :region animated : YES ]; }]; Dans la méthode geocodeaddressstring:completionhandler:, le premier argument est un NSString contenant l adresse recherchée et le deuxième argument est de type ^(NSArray *placemarks, NSError *error). C est donc un bloc, une fonction qui sera appelée après avoir réceptionné la réponse à la requête Castellane, Marseille. Plus besoin d intérroger le service Google, ni de traiter le résultat avec des NSString ou NSXMLParer.

Ouvrez le projet du TP précédent et modifiez le de façon intégrer cette dernière trouvaille. La complétion proposée par XCode, met en évidence les arguments des méthodes (on peut passer d un argument à l autre avec la touche Tab). Lorsque l argument de type bloc est ainsi surligné, appuyez sur Entrée : les accolades du bloc sont directement ajoutées, il ne reste plus qu à ajouter le code dans le corps du bloc. N oubliez pas d ajouter un point virgule après le crochet fermant de la fonction geocodeaddressstring:completionhandler:. Géolocalisation Nous allons ajouter une fonctionalité de géolocalisation à notre application. L application comptera la distance parcourue (depuis son dernier lancement ou réinitialisation), affichera la position courante et le tracé du parcours sur la carte. Initialisation et configuration du locationmanager L API du framework CoreLocation contient la classe CLLocationManager qui permet l accès, le démarrage et l arrêt des différentes ressources de localisation du terminal (position GPS ou autre, boussole, bluetooth). Nous devrons donc instancier un objet de cette classe. Déclarez une variable de type CLLocationManager: CLLocationManager *locationmanager; Dans la fonction ViewDidLoad de la classe ViewController, instanciez cette variable : locationmanager =[[ CLLocationManager alloc ] init ]; Parcourez la documentation ou naviguez dans les fichiers header (via un cmd + clic sur le nom d une classe) pour vous renseigner sur le fonctionnement de CLLocationManager. Vous avez trouvé le nom du protocole associé à cette classe? En effet, CLLocationManager utilise aussi la délégation pour fonctionner. Ainsi, les méthodes startupdatinglocation et stopupdatinglocation permettent respectivement de démarrer et arrêter le service de localisation, tandis que la méthode locationmanager:didupdatelocations: du protocole CLLocationManagerDelegate sera appelée à chaque fois que la position change. Dans notre cas, la classe ViewController sera le délégué de CLLocationManager. Modifiez ViewController.h en conséquence :

@interface ViewController: UIViewController < UITextFieldDelegate, CLLocationManagerDelegate > Dans la méthode viewdidload de ViewController.m, après l initialisation de locationmanager, vous pouvez configurer cet objet (regardez notamment les propriétés distancefilter et desiredaccuracy ), puis ajoutez : locationmanager. delegate = self ; Avec ios7, l accès à la position de l utilisateur ne nécessite pas d autorisation (!). Nous pouvons donc directement démarrer la géolocalisation : [ locationmanager startupdatinglocation ]; Depuis ios8, l accès à la position de l utilisateur nécessite une autorisation. Si vous utilisez une version de XCode avec le SDK ios 8, vous devrez d abord spécifier que l application effectuera cette demande : dans le panneau de configuration du projet, allez dans l onglet Info et ajoutez une entrée à la liste Custom ios Target Properties. L entrée est de type String et sa clé est NSLocationWhenInUseUsageDescription. Dans viewdidload, une fois le locationmanager configuré (regardez notamment les propriétés distancefilter et desiredaccuracy ), on vérifie le status d autorisation. S il est indeterminé, il faut faire la demande d autorisation. Si la demande a déjà été validée, on peut démarrer le service. Sinon, on affiche un message sur la console. CLAuthorizationStatus status=[ CLLocationManager authorizationstatus ]; if (status== kclauthorizationstatusnotdetermined ){ [ locationmanager requestwheninuseauthorization ]; } else if (status== kclauthorizationstatusauthorizedwheninuse ){ [ locationmanager startupdatinglocation ]; } else { NSLog ( @"Notallowedtoaccesscurrentlocation" ); } A la première exécution, la méthode de délégué locationmanager:didchangeauthorizationstatus: est appelée. Si tout est bon, c est le moment de démarrer le service de localisation. Ajoutez la méthode suivante dans ViewController.m : // ForiOS8compatibility: needtogetauthorizationforlocationtracking -( void )locationmanager:( CLLocationManager *)manager didchangeauthorizationstatus:( CLAuthorizationStatus )status{ if (status== kclauthorizationstatusauthorizedwheninuse ){ [manager startupdatinglocation ]; } }

Pour aller plus loin : https://developer.apple.com/library/ios/documentation/userexperience/conceptual/locationa warenesspg/corelocation/corelocation.html Distance parcourue Nous allons maintenant nous concentrer sur le suivi de la position de l utilisateur. Dans un premier temps, l application va compter la distance parcourue depuis le démarrage du service : Dans la classe ViewController, ajoutez la variable totaldistance de type double ; et dans viewdidload, initialisez cette variable à 0. Lorsque la position est mise à jour, la méthode locationmanager:didupdatelocations: est appelée. Le deuxième argument est un tableau qui contient des objets CLLocation rangés par ordre chronologique (le dernier est le plus récent). Vous pouvez connaître la distance en mètres entre deux positions grâce à la méthode distancefromlocation:. Il semblerait que le simulateur ne maintienne pas l historique des positions : le tableau de CLLocation n a toujours qu un seul objet. A vous donc de conserver la position précédente dans une variable oldposition. Implémentez cette méthode et affichez la distance parcourue dans le UILabel. Attention, les quelques premiers appels à cette méthode retournent des positions souvent très érronées. Il est possible de vérifier la précision estimée par les propriétés horizontalaccuracy et verticalaccuracy ; sinon, vous pouvez juste ignorer les cinq premiers appels à cette méthode. Ajoutez le suivi de la position sur la carte. Notez qu il est possible de simuler un déplacement sur le Simulateur : Menu Debug/Location/ Modifiez le comportement du UISwitch pour qu il mette en pause (démarre/arrête) la géolocalisation. Ainsi, la recherche d une adresse (geocoding) ne fonctionnera que lorsque le switch est éteint. Vous pouvez écrire Saisir une adresse : dans le UILabel lorsque le switch est éteint et cacher le UITextField lorsque le switch est allumé. Tracé du parcours Si ce n est pas déjà fait, ajoutez le protocole MKMapViewDelegate dans la déclaration de la classe ViewController, et ajoutez l instruction suivante dans viewdidload : mapview. delegate = self ;

Pour afficher le tracé du parcours sur la carte, plusieurs solutions s offrent à nous, nous utiliserons les capacités de la classe MKMapView et du protocole MKMapViewDelegate. Les objets affichables sur la carte doivent implémenter le protocole MKOverlay : nous ajouterons des MKPolyline qui implémentent ce protocole. Dans la méthode locationmanager:didupdatelocations:, construisez un objet MKPolyline à partir des deux positions précédente et courante. Ajoutez cet objet à votre MKMapView par l appel à la méthode d instance addoverlay:. Le rendu visuel de ces objets est déterminé dans un deuxième temps par l appel à la méthode du délégué MKMapViewDelegate mapview:rendererforoverlay:. Voici une façon de générer un rendu pour un objet MKPolyline : -( MKOverlayRenderer *)mapview:( MKMapView *)mapviewrendererforoverlay:( id < MKOverlay >)overlay { MKPolylineRenderer * lineview=[[ MKPolylineRenderer alloc ] initwithpolyline :overlay]; lineview. strokecolor =[ UIColor bluecolor ]; lineview. linewidth = 5 ; return lineview; } Réinitialisation du suivi par détection d une secousse Avant de terminer ce TP, nous allons ajouter une dernière fonctionalité à notre application : nous souhaitons réinititaliser le suivi et la distance parcourue en agitant le terminal ios. La réinitialisation consiste à : Remettre à zéro la variable totalmeters, Enlever les MKOverlay de la carte. Regardez bien la documentation, un objet MKMapView peut supprimer plusieurs MKOverlay passés en arguments dans un NSArray. Vous devrez donc maintenir une collection de MKOverlay préalablement ajoutés... Pour éviter une réinitialisation fortuite, la réinitialisation ne se fera que lorsque le bouton UISwitch est positionné sur Off. Ajouter un feedback visuel indiquant la réinitialisation. Plusieurs solutions s offrent à nous pour détecter la secousse de l appareil. Nous allons voir une façon naturelle de le faire, basée sur la détection de Gesture. (une autre façon, de plus bas niveau ferait appel au framework CoreMotion.) La classe ViewController hérite de UIViewController qui hérite de UIResponder. UIResponder est la classe responsable de la gestion des évènements (Touch, Motion, ). Du fait de cet

héritage, nous pouvons directement surcharger l une des méthodes de UIResponder qui nous intéresse. Allez dans la documentation et retrouvez le nom de la méthode qui capturera l évènement Shake. Ajoutez la méthode retrouvée dans la documentation et implémentez le comportement décrit précédemment. Le feedback visuel peut consister à afficher le message Réinitialisation en rouge pendant une seconde. Nous allons utiliser les fonctionalités du Framework Dispatch pour cela. Dispatch (ou GCD ) est un Framework pour accorder la concurrence entre des exécutions de blocs. L API est écrite en C, elle permet d exécuter des blocs de façon synchrone ou asynchrone dans des Threads distincts. Nous utiliserons la fonction dispatch_after pour programmer l exécution d un bloc (une seconde plus tard). La documentation de GCD et les paramètres des fonctions peuvent sembler peu claires. Pas de panique, XCode complète judicieusement l appel aux différentes fonctions, et le tout s avère finalement très simple! Appuyez sur Entrée après avoir écrit dispatch_after : magie. Dans la méthode motionended:withevent: (vous l aviez trouvé n est ce pas?) après la réinitialisation, modifiez le texte du UILabel pour afficher le message Réinitialisation en rouge. Puis, dans un bloc dispatch_after, repassez le texte et la couleur d origine (probablement Saisir une adresse ). Amélioration de l interface graphique Cette partie vise à enrichir le rendu visuel de l application en vue d une meilleure interaction avec l utilisateur. D abord, nous ajouterons une animation pour montrer/cacher le UITextField selon l état du UISwitch. Puis, nous modifierons le comportement de la carte pour, en plus de suivre la position, s oriente selon la direction de l utilisateur. Les animations apportent des effets visuels nécessaires à une meilleure interaction avec l utilisateur, permettant une meilleure prise en main, et participent ainsi à une meilleure perception générale de l application. Evidemment, les animations ne concernent que les éléments graphiques de UIKit. En particulier, certaines propriétés sont animables. Par l utilisation simple de blocs, le développeur définie l état final dans lequel l objet doit se trouver, et Core Animation se charge du rendu intermédiaire. Voici la liste des propriétés animables, d après la documentation officielle. https://developer.apple.com/library/ios/documentation/windowsviews/conceptual/viewpg_ip honeos/animatingviews/animatingviews.html

Les blocs d animation sont appelés depuis des méthodes de classe de UIVIew. Par exemple, le code suivant modifie la propriété alpha de adressetextfield pendant 0.5 seconde jusqu à la valeur 0 : [ UIView animatewithduration :.5 animations :^{ adressetextfield. alpha = 0 ; }]; Le code suivant modifie la position de adressetextfield selon l état de switchbutton : [ UIView animatewithduration :.5 animations :^{ CGRect frame= adressetextfield. frame ; frame. origin. y = switchbutton. ison? 50. : 0. ; adressetextfield. frame =frame; }]; Remarque : frame.origin.x n est pas directement assignable, il faut donc modifier toute la structure frame. Modifiez le rendu de la vue depuis le StoryBoard ; la carte prend dorénavent toute la taille de la vue ; le label s étend sur toute la largeur, collé sur le haut de l écran, avec une légère transparence ; le textfield est juste en dessous du label, étiré aussi sur toute la largeur et avec la même transparence. Ajoutez une animation de votre choix sur adressetextfield pour le rendre visible uniquement lorsque le bouton UISwitch est éteint. Veillez bien à placer initialement le textfield dans sa position cachée si l application démarre avec le UISwitch allumé.

Nousallonsmaintenantorienterlacarteenfonctiondesmouvementsdel utilisateur.pour cela,nousutiliseronslecapteurdedirection(heading)intégréau locationmanager :les méthodes startupdatingheading et stopupdatingheading fonctionnentcomme start/stopupdatinglocation et appellent laméthodededélégué locationmanager:didupdateheading: pouravertirlecontroleurd unchangementdedirection. Retrouvezcesméthodesdansladocumentation. Ajoutezledémarrage/l arrêtducapteurdedirectionenmêmetempsquele démarrage/l arrêtducapteurdelocalisation. Ajoutezlaméthodededéléguéquiconvient,vousconstaterezquenousrécupérons ainsiunobjetdetype CLHeading dontlapropriété trueheading nousintéresseratout particulièrement. Pourtestercettefonctionnalité,vousdevrezutiliserunvraiterminaliOSplutôtquele simulateur.n essayezpasdetournerlesimac )

Pour orienter la carte avec la direction de l utilisateur, nous appliquerons une transformation affine sur notre objet de type MKMapView (rappelez vous que la propriété transform est animable...). Nous effectuerons une rotation du composant graphique qui donnera l impression que son contenu s oriente avec l utilisateur. Recherchez dans la documentation la propriété transform. Trouvé? C est une propriété de la classe UIView (dont hérite MKMapView) qui est de type CGAffineTransform. Parcourez la référence pour retrouver les fonctions C qui permettent de définir une transformation affine, vous trouverez notamment la fonction CGAffineTransformMakeRotation Depuis le StoryBoard, redimensionnez la carte de façon à ce qu elle soit trois fois plus grande (en largeur et hauteur) et centrée sur le centre de la vue. Ainsi, lorsque nous appliquerons une rotation, la carte apparaîtra toujours en plein écran. Dans la méthode de délégué locationmanager:didupdateheading:, modifiez la propriété transform de mapview pour effectuer la rotation. Attention, trueheading est en degré, tandis que CGAffineTransformMakeRotation utilise des angles en radians. Comme transform est une propriété animable, vous pouvez ajouter un bloc d animation pour rendre la rotation plus naturelle.