Ludovic ROLAND

Blog technique sur mes expériences de développeur.

Windows Phone 7 : Appeler un webservice

6 février 2012

Dans un précédent billet, je vous montrais comment accéder à l’API Twitter au sein d’une application Android (voir l’article).

Cette fois ci, nous allons voir comment procéder au sein d’une application Windows Phone 7.

Petit rappel : qu’est ce qu’un web service ?

Un service web (ou service de la toile) est un programme informatique permettant la communication et l’échange de données entre applications et systèmes hétérogènes dans des environnements distribués. Il s’agit donc d’un ensemble de fonctionnalités exposées sur internet ou sur un intranet, par et pour des applications ou machines, sans intervention humaine et de manière synchrone. [Wikipédia](http://fr.wikipedia.org/wiki/Service_Web)

Petit rappel 2 : l’API Twitter

L’API Twitter permet d’avoir accès aux tweets de n’importe quel compte le tout au format XML.

Les informations sont accessibles à l’adresse http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=UserUser est bien évidemment à remplacer par le nom du compte auteur des tweets que vous souhaitez consulter.

Comme vous pouvez le voir, la balise racine du fichier XML est la balise <statuses>. Chaque tweet est quant à lui représenté par une balise <status>. L’API est très complète et permet de connaître à chaque fois le contenu du tweet (balise <text>), la date de ce dernier (la balise <created_at>), ainsi que d’autres informations comme par exemple s’il s’agit d’un retweet (balise <retweeted>) et toutes les informations concernant l’auteur du tweet (balise <user>).

L’implementation C#

Pour rester fidèle à mon premier article, il conviendra de récupérer uniquement le contenu des tweets. Nous allons donc nous intéresser à la balise <text>.

Appel du web service

La première question que l’on doit se poser lorsqu’on appelle un web service concerne la classe que nous allons utiliser : HttpWebRequest ou WebClient ?

D’autres tutoriels utilisent la classe WebClient sans pour autant fournir d’explication. Il est temps de lever le mystère !

Pour faire simple, la classe Webclient lève l’évènement de fin de requête dans le thread de l’interface graphique alors que la classe HttpWebRequest lève le même évènement dans un thread lancé en arrière plan. De manière générale et c’est d’autant plus vrai sur un téléphone, il n’est pas conseillé de lancer des actions de traitement dans le thread de l’interface graphique. En effet, ça gène grandement la navigation et pour peu que le traitement soit long, l’application paraitra « freezée » pendant quelques secondes. Il conviendra donc d’utiliser la classe HttpWebRequest par soucis de bonne pratique.

La première étape consiste donc à déclarer le thread dans lequel va s’exécuter notre appel à l’API Twitter  :

namespace Twitter
{
    public partial class MainPage : PhoneApplicationPage
    {
        private BackgroundWorker backgroundWorker;
    }
}

Dans un soucis de simplicité, notre thread va se lancer automatiquement au lancement de notre page. C’est donc dans le constructeur que se passe la prochaine étape :

// Constructeur
public MainPage()
{
    InitializeComponent();

    //On instancie notre thread
    backgroundWorker= new BackgroundWorker();

    //On définit la méthode qui va être appelée au lancement de notre thread
    backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

    //On lance la tâche de manière asynchrone.
    backgroundWorker.RunWorkerAsync();
}

Il faut maintenant créer la méthode backroungWorker_DoWork et la compléter en appelant enfin notre web service :

void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    try
    {
        //Création de la requête HTTP
        HttpWebRequest rqst = HttpWebRequest.CreateHttp("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=User");
        rqst.AllowReadStreamBuffering = true;

        //Obtention de la réponse
        rqst.BeginGetResponse(result =&gt;
        {
            //Récupération du document XML et mise en place de l'exploitation des données
            WebResponse response = rqst.EndGetResponse(result);
            XDocument doc = XDocument.Load(response.GetResponseStream());
            response.Close();

            Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
            {
                //TRAITEMENT DES INFORMATIONS
            });
        }, null);
    }
    catch(Exception ex)
    {
        System.Diagnostics.Debug.WriteLine(ex.Message);
    }
}

Des erreurs ?

A ce niveau du programme, il est fort probable que Visual Studio vous souligne la classe XDocument et vous dise quelque chose du genre :

Et effectivement, c’est bien le cas ! Pour corriger, le problème, vous devez ajouter la référence System.Xml.Linq à votre projet.

Une fois fait, n’oubliez pas le using qui va avec :

using System.Xml.Linq;

Exploitation des donnees

Comme il a déjà été dit, nous allons nous contenter d’afficher le texte des différents tweets :

foreach (var tweet in doc.Descendants("status"))
{
    System.Diagnostics.Debug.WriteLine(tweet.Element("text").Value);
}

Libre à vous maintenant d’exploiter les données comme bon vous semble au sein de votre application !

##L e code complet

Pour ceux qui en auraient besoin, voici le code complet du programme que nous venons d’écrire.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.ComponentModel;
using System.Xml.Linq;

namespace Twitter
{
    public partial class MainPage : PhoneApplicationPage
    {
        private BackgroundWorker backgroundWorker;

        // Constructeur
        public MainPage()
        {
            InitializeComponent();

            //On instancie notre thread
            backgroundWorker = new BackgroundWorker();

            //On définit la méthode qui va être appelée au lancement de notre thread
            backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

            //On lance la tâche de manière asynchrone.
            backgroundWorker.RunWorkerAsync();
        }

        void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            try
            {
                HttpWebRequest rqst = HttpWebRequest.CreateHttp("http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=Sjukmusik");
                rqst.AllowReadStreamBuffering = true;

                //Obtention de la réponse
                rqst.BeginGetResponse(result =&gt;
                {
                    //Récupération du document XML et mise en place de l'exploitation des données
                    WebResponse response = rqst.EndGetResponse(result);
                    XDocument doc = XDocument.Load(response.GetResponseStream());
                    response.Close();

                    Deployment.Current.Dispatcher.BeginInvoke(() =&gt;
                    {
                        foreach (var tweet in doc.Descendants("status"))
                        {
                            System.Diagnostics.Debug.WriteLine(tweet.Element("text").Value);
                        }
                    });
                }, null);
            }
            catch (Exception ex)
            {
                System.Diagnostics.Debug.WriteLine(ex.Message);
            }
        }
    }
}

A lire aussi :

Commentaires