Windows Phone 7.5–Manejando llamadas a Servicios


Mientras preparo un post de un tamaño bastante considerable (ya me está llevando algo de tiempo documentarme para completarlo) he decidido sacar una pequeña entrada con algo de información que me ha resultado bastante útil en el proyecto personal que voy llevando a cabo.

Accediendo a FourSquare

Una parte fundamental del proyecto es el acceso al API de FourSquare. Este API está basada en un conjunto de servicios REST muy bien diseñados y fáciles de comprender (bueno, al menos en cierta parte).

image

Uno (entre muchos) de los aspectos interesantes del API es el soporte a varios idiomas. Según indica la documentación, existen dos formas para solicitar las respuestas en uno de los idiomas soportados por FourSquare.

Una de ellas es especificar un parámetro (locale=xx) dentro de la petición HTTP, sin embargo el método favorito es utilizar una cabecera HTTP (Accept-Language). Así que, sin dudarlo, y aprovechando que la infraestructura que monté para llamar a los diferentes end-points de FourSquare me lo permitía con facilidad, me decidí a incluir la cabecera para el idioma.

Todos los end-points heredan de una clase base llamada FourSquareEndPointBase.cs, donde se gestiona de forma asíncrona las peticiones y respuestas realizadas por la aplicación. Entre las responsabilidades de esta clase está, lanzar asíncronamente la petición al end-point que especifique la clase hija, recibir la información desde FourSquare, comprobar el estado de la llamada y pasarle a la clase hija la respuesta jSon para que ella se encargue de Deserializar dicho jSon a las clases de entidad necesarias.

La siguiente porción de código pertenece al método que realiza asíncronamente la llamada al end-point de FourSquare.

   1: protected void BeginRequest(Uri url, string method)

   2: {

   3:    HttpWebRequest request = WebRequest.CreateHttp(url);

   4:  

   5:    request.Headers["Accept-Language"] = System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName;

   6:    request.Method = method;

   7:  

   8:    CallbackResult asyncResult = new CallbackResult

   9:    {

  10:        Request = request,

  11:        JsonResponse = null

  12:    };

  13:  

  14:    request.BeginGetResponse(_callback, asyncResult);

  15: }

Como podéis ver, la cabecera HTTP “Accept-Language” se informa con el idioma actual del hilo de interfaz de usuario (el método de la petición puede ser GET o POST en esta versión del framework de acceso a FourSquare que he montado).

Hasta aquí no hay ningún misterio. Mirando el código me acordé de un proyecto que realicé años atrás en el antiguo PocketPC Phone Ed. 2003. Y, me lancé a mirar si:

  1. ¿Me permitirá FourSquare me permitiría pedir respuestas comprimidas?
  2. ¿Me permitirá Windows Phone descomprimir respuestas en caso de que me lleguen comprimidas?

Solicitando Compresión en las respuestas de FourSquare (y de quien quiera darlas)

El proceso para solicitar una respuesta comprimida es muy similar al descrito un poco más arriba.

   1: protected void BeginRequest(Uri url, string method)

   2: {

   3:     HttpWebRequest request = WebRequest.CreateHttp(url);

   4:  

   5:     request.Headers["Accept-Language"] = System.Threading.Thread.CurrentThread.CurrentUICulture.TwoLetterISOLanguageName;

   6:     request.Headers["Accept-Encoding"] = "gzip";

   7:     request.Method = method;

   8:  

   9:     CallbackResult asyncResult = new CallbackResult

  10:     {

  11:         Request = request,

  12:         JsonResponse = null

  13:     };

  14:  

  15:     request.BeginGetResponse(_callback, asyncResult);

  16: }

Como podéis ver, he añadido una segunda cabecera HTTP en la que indico que acepto como codificación de la respuesta, una codificación comprimida como “gzip”.

El siguiente paso es ver si FourSquare responde comprimiendo o no…

image

En la captura de pantalla se aprecia, inspeccionando el correspondiente objeto con el depurador, que la respuesta contiene una cabecera “Content-Encoding” y que su contenido es “gzip” lo que significa que: ¡FourSquare admite compresión!

Bien, acabo de estropear todo mi código. Ya que, las clases utilizadas para deserializar el jSon se estrellan irremediablemente contra un chorro de caracteres sin sentido. Es hora de descomprimir la respuesta.

Windows Phone no da soporte nativo a la compresión HTTP

Como he podido verificar después de dar unas cuantas vueltas, así que es hora de echar mano de (otra) biblioteca de terceros como SharpCompress.

Busqué el paquete en NuGet y, voilà. Ahí estaba.

image

¡Magnífico, incluso en la versión para Windows Phone 7! Ahora manos a la obra.

image

Y el código que se encarga de descomprimir la respuesta cuando corresponda.

   1: using SharpCompress.Compressor;

   2: using SharpCompress.Compressor.Deflate;

   3:  

   4: ...

   5:  

   6: response = (HttpWebResponse)request.EndGetResponse(ar);

   7:  

   8: byte[] buf = new byte[8192];

   9:  

  10: Stream respStream;

  11: if (response.Headers["Content-Encoding"] != null && response.Headers["Content-Encoding"] == "gzip")

  12: {

  13:     respStream = new GZipStream(response.GetResponseStream(), CompressionMode.Decompress);

  14: }

  15: else

  16: {

  17:     respStream = response.GetResponseStream();

  18: }

  19:  

  20: ...

Como podéis ver, muy sencillo y, de un plumazo, acabamos de ahorrarle a nuestro usuario algún que otro gasto en la factura telefónica (bueno, se lo hemos cambiado por algo más de consumo de batería)

Anuncios

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s