Inicio > Desarrollo, Tutorial, Windows Phone > Tutorial: Leer Twitter en Windows Phone 7 con el mínimo esfuerzo

Tutorial: Leer Twitter en Windows Phone 7 con el mínimo esfuerzo

En este tutorial vamos a comprobar lo sencillo que es explotar servicios online en una aplicación Windows Phone 7 y de paso conocer un poco más las herramientas de desarrollo para esta plataforma.

Actualización: Lo siento mucho chicos, pero Twitter cambió hace unos meses su API para evitar, precisamente, aplicaciones como esta. Las técnicas de programación para Windows Phone siguen siendo válidas, pero mucho me temo que descargar los tweets, ya no.

Aunque parezca increíble, no tengo cuenta en Twitter. Sí, lo sé, podéis decirme lo que queráis, creo que simplemente no es para mi. Lo cual no quita para que sea un ávido lector de tweets de mucha gente, particularmente de fuentes técnicas y si (debilidad de uno) del mundillo de la Fórmula 1 y del de motociclismo. La ventaja es que no hace falta tener cuenta en Twitter para leer los mensajes de otros, y el portal pone a disposición de los programadores un amplísimo surtido de servicios web para acceder a la información.

Así que vamos a hacer, paso a paso, un lector de Tweets para Windows Phone 7. Para este tutorial he utilizado Visual Studio 2010 junto con el SDK de Windows Phone 7.5 Mango, pero vamos a seleccionar como “target” Windows Phone 7.0 “actual”.

Crear el proyecto

El primer paso es abrir VisualStudio y crear un nuevo proyecto para Windows Phone 7: seleccionamos el menú “File”, “New”, “Project” y podremos elegir el tipo de proyecto que deseemos. De las plantillas instaladas buscaremos “Visual C#”, y dentro de éstas “Silverlight for Windows Phone”. A la derecha podremos elegir “Windows Phone Application”.

En la parte inferior del diálogo de creación del nuevo proyecto escogeremos un directorio de trabajo y un nombre para nuestro nuevo y flamante programa. Yo he llamado al mío “tweetRead”:

image

En la parte superior del diálogo aparece un selector con la versión a utilizar de .Net Framework: dado que vamos a realizar una aplicación para WIndows Phone, la selección es indiferente, porque el target es Silverlight para WIndows Phone.

Una vez creado el proyecto, aparecerá abierta la página principal en Visual Studio, listo para empezar a realizar cambios:

image

Perfilemos el interface de usuario

Visual Studio crea un proyecto a partir de una plantilla con el formato predeterminado de las aplicaciones para WP7. En nuestro caso, vamos a reducir el interface para ir directamente a la implementación. Así que buscaremos en el fuente XAML el fragmento que define la cabecera de la aplicación (“TitlePanel”) y lo reemplazaremos por una Grid con los controles que nos permitirán seleccionar un usuario de Twitter. Vamos a reemplazar totalmente este fragmento:

<StackPanel x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>
<TextBlock x:Name=”ApplicationTitle” Text=”MY APPLICATION” Style=”{StaticResource PhoneTextNormalStyle}”/>
<TextBlock x:Name=”PageTitle” Text=”page name” Margin=”9,-7,0,0″ Style=”{StaticResource PhoneTextTitle1Style}”/>
</StackPanel>

Por este otro:

<!–ContentPanel – place additional content here–>
<Grid x:Name=”TitlePanel” Grid.Row=”0″ Margin=”12,17,0,28″>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width=”Auto”/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row=”0″ Grid.ColumnSpan=”2″ Text=”Tweets recientes de”/>
<TextBox Grid.Row=”1″ Grid.Column=”0″ x:Name=”tweetName”/>
<Button Grid.Row=”1″ Grid.Column=”1″ Content=”Ir!” x:Name=”btnLoad” Click=”TweetLoadClicked” />
</Grid>

Hemos reemplazado la cabecera clásica por algo un poco más “funcional” en nuestro ejemplo: un campo de texto donde el usuario escribirá la fuente de tweets que desea leer y un botón que lanza la descarga. Hemos aprovechado incluso para definir qué función se encargará del evento “Click” del botón, la función “TweetLoadClicked”. En cuanto hayamos pegado este fragmento, la simulación del interface cambiará completamente a algo parecido a esto:

image

Un poco más abajo se declara una Grid con el contenido de la página del programa. En este caso vamos a añadir un control ListBox que será el que finalmente muestre los mensajes:

<!–ContentPanel – place additional content here–>
<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>
<ListBox x:Name=”tweetFeed”>
</ListBox>
</Grid>

Al código!

Ahora es cuando vamos a empezar a añadir funcionalidad a la aplicación. Para ello, hacemos doble click sobre el archivo de código del formulario (MainPage.xaml.cs), para encontrarnos con el desolador espectáculo de una clase que no hace “casi” nada:

image

Si recordamos de antes, tenemos un TextBlock cuyo evento “Click” va a ejecutar la función TweetLoadClicked. La función iniciará la descarga de los tweets usando el nombre tecleado por el usuario:

private void TweetLoadClicked(object sender, RoutedEventArgs e)
{
WebClient tweetRequest = new WebClient();
tweetRequest.DownloadStringCompleted += new DownloadStringCompletedEventHandler(DownloadComplete);
tweetRequest.DownloadStringAsync(new Uri(@”
http://api.twitter.com/1/statuses/user_timeline.xml?screen_name=” + tweetName.Text));
}

El método DownloadStringAsync() de WebClient simplemente descarga el contenido de la url que le demos y una vez terminado invoca el evento que se haya definido en DownloadStringCompleted (en nuestro caso, será la función “DownloadComplete”). Así que para poder experimentar un poco, vamos a empezar la función y ver qué pasa:

void DownloadComplete(object sender, DownloadStringCompletedEventArgs e)
{
System.Diagnostics.Debug.WriteLine(e.Result);
}

Si ponemos un breakpoint en la línea con el WriteLine y ejecutamos el programa, podremos ver si funciona. Así que pulsamos F5, arrancará nuestro querido emulador y nuestro programa tomará el control. Vamos a pedir tweets de Engadget, a ver qué pasa:

image

Cuando pulsemos el botón “Ir!” la función TweetLoadClicked comenzará su trabajo y empezará a descargar el contenido usando los APIs de Twitter. Unos segundos más tarde, VisualStudio se detendrá en el breakpoint con los resultados. Basta con colocar el ratón sobre la palabra “Result” para que aparezcan los contenidos:

image

Si necesitamos analizar la información con más detalle, podemos emplear el visor que aparece al selecciona el menú con la lupa a la izquierda y seleccionar el visor XML:

image

Veremos directamente la información XML enviada por Twitter:

image

Mostrando los resultados

Bueno, esto está muy bien, pero ahora toca ver los resultados de nuestros denodados esfuerzos de programación. Lo primero, vamos a desensamblar los contenidos XML de la respuesta del servidor en algo un poco más manejable, y para ello usaremos nuestro querido XmlReader para ir desensamblando los fragmentos de información enviados por el servidor. Pero antes, vamos a crear una clase que contiene la información de un tweet. Para ello, en VisualStudio pulsaremos con el botón derecho sobre el proyecto tweetRead y seleccionaremos “Add Class” (añadir clase):

image

Como nombre de archivo emplearemos “Tweet.cs”, y usaremos el código siguiente:

using System;

namespace tweetRead
{
public class Tweet
{
public string message { get; set; }
public string userName { get; set; }
public String imageUrl { get; set; }
}
}

Volviendo a la función DownloadComplete, vamos a cambiarla por algo más “funcional” que lo que hasta ahora hace:

void DownloadComplete(object sender, DownloadStringCompletedEventArgs e)
{
List<Tweet> Tweets = new List<Tweet>();
using (System.Xml.XmlReader reader = System.Xml.XmlReader.Create(new System.IO.StringReader(e.Result)))
{
while (reader.ReadToFollowing(“status”))
{
reader.ReadToFollowing(“text”);
String msg = reader.ReadElementContentAsString();
reader.ReadToFollowing(“user”);
reader.ReadToFollowing(“name”);
String user = reader.ReadElementContentAsString();
reader.ReadToFollowing(“profile_image_url”);
String url = reader.ReadElementContentAsString();

      Tweets.Add(new Tweet()
{
message = msg,
userName = user,
imageUrl = url
});
}
}
tweetFeed.ItemsSource = Tweets;
}

Empleando un XmlReader, recorremos los elementos de respuesta del servidor, creando instancias de nuestra clase Tweet y almacenándolos en un array. Una vez leídos todos, asignamos el array como origen de datos (ItemSource) del ListView.

Sólo queda una cosa por hacer: definir el formato de cada Tweet en nuestro interface de usuario. Si recordáis, nuestro ListView estaba completamente vacío, pero le estamos pasando directamente una colección de objetos Tweet. Para definir el aspecto final de un Tweet en el interface de usuario, añadiendo simplemente la definición para “un ítem” definiendo el “ItemTemplate” del control, incluyendo propiedades que debe presentar. Así que vamos a ampliar la declaración del ListBox con el formato completo:

<!–ContentPanel – place additional content here–>
<Grid x:Name=”ContentPanel” Grid.Row=”1″ Margin=”12,0,12,0″>
<ListBox x:Name=”tweetFeed”>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin=”0,0,0,10″>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=”Auto”/>
<ColumnDefinition Width=”*”/>
</Grid.ColumnDefinitions>
<Image Grid.Column=”0″ Source=”{Binding imageUrl}” VerticalAlignment=”Top”/>
<Grid Grid.Column=”1″ Margin=”5″>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Grid.Row=”0″ Text=”{Binding userName}” VerticalAlignment=”Top” Style=”{StaticResource PhoneTextAccentStyle}”/>
<TextBlock Grid.Row=”1″ Text=”{Binding message}” TextWrapping=”Wrap” VerticalAlignment=”Top” Style=”{StaticResource PhoneTextNormalStyle}”/>
</Grid>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>

El “truco” es, simplemente, el valor para los campos que nos interesen de los controles (Text en nuestro caso). En lugar de establecer un valor concreto, empleamos la sintáxis “{Binding <campo>}”, haciendo que los controles “busquen” una propiedad con ese nombre del ItemSource (en el caso del ListBox) que le asignemos, que es la única fuente a la información que el código ha tenido que establecer. De igual manera, el control imagen tiene asignada su propiedad Source a otro de los campos.

Esta es la parte fantástica de Silverlight: en el código no hay absolutamente ninguna referencia al formato en pantalla de los datos, simplemente se preparan, se “empaquetan” y se le envían al interface de usuario. El interface “sabe” cómo debe presentar los datos, pero desconoce totalmente el origen o formato original de los mismos. De esta forma, manipular el formato en pantalla, adaptarlo a otras resoluciones o formatos, se convierte en una tarea totalmente desvinculada de la programación.

Como prueba final, vamos a ver cómo queda el programa con todos los cambios:

image

No es el cliente Twitter definitivo, pero para estar hecho en media hora no está mal. Lo importante es lo sencillo que es consumir servicios web desde Windows Phone y la potencia del databinding para separar el código de la presentación.

Anuncios
Categorías:Desarrollo, Tutorial, Windows Phone Etiquetas: , ,
  1. kevin ricardo sejin
    13/Abr/2012 en 10:41 pm

    Como hago si quiero leer por lo menos 3 cuentas mas ? que parte del codigo cambió y como ?

    • 16/Abr/2012 en 10:36 am

      @kevin: la cosa se resume en ejecutar varias veces algo parecido a la función “TweetLoadClicked()”, a la que puedas pasar una cuenta como argumento. Cada llamada descarga una de las cuentas. Tendrás que modificar la función “DownloadComplete()” para que en lugar de reemplazar todos los tweets con los últimos descargados, los “añada” a la colección (y ordene los tweets por fecha).

      • Antonio
        08/May/2013 en 11:02 pm

        tienes algun ejemplo?
        he estado buscando como implementarlo y no he podido como hacer que baje informacion de varias cuentas

  2. kevin ricardo sejin
    17/Abr/2012 en 4:06 am

    EfePuntoMarcos :
    @kevin: la cosa se resume en ejecutar varias veces algo parecido a la función “TweetLoadClicked()”, a la que puedas pasar una cuenta como argumento. Cada llamada descarga una de las cuentas. Tendrás que modificar la función “DownloadComplete()” para que en lugar de reemplazar todos los tweets con los últimos descargados, los “añada” a la colección (y ordene los tweets por fecha).

  3. jesus
    03/Jun/2012 en 9:19 pm

    como seria si quiero publicar un tweet en una cuenta

  1. No trackbacks yet.

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

A %d blogueros les gusta esto: