Si eres un desarrollador de aplicaciones y estás comenzando con una nueva plataforma definitivamente vas a hacer un “Hola mundo”. Después de hacerlo, el siguiente paso es comenzar a explorar la posibilidad de recibir datos y acomodarlos de manera ordenada y agradable a la vista de los usuarios. En este artículo vamos a ver como puedes hacer una aplicación básica de lectura de feeds que es un gran ejemplo de como manejar archivos XML. Lo más importante de esto es como hacerlo en las dos versiones de Windows Phone que ahora se encuentran disponibles así que comencemos.
Primero hablemos de la interfaz, en el caso de Windows Phone el control para mostrar la información puede ser idealmente el LongListSelector gracias a su rendimiento y facilidad de implementación, en el caso de Windows Phone 8.1 el control ideal puede ser el ListView que coincide visualmente con la interfaz de RT y obviamente es mucho más sencillo. En el ejemplo usaremos un ListBox, la opción de menores posibilidades pero es el único común denominador entre las dos plataformas.
<Grid x:Name="LayoutRoot" Background="Transparent"> <ListBox Name="lstNotas"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Orientation="Horizontal" Height="200"> <Image Width="150" Height="150" Source="{Binding Imagen}"/> <StackPanel Orientation="Vertical"> <TextBlock Text="{Binding Titulo}" FontSize="20"/> <TextBlock Text="{Binding Descripcion}" FontSize="15"/> </StackPanel> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox> </Grid> |
Además de esto, crea una clase que sea capaz de contener los atributos que deseas usar, para este ejemplo, serán cuatro los atributos que utilizaremos del feed. Los atributos convertidos en propiedades son los siguientes.
namespace FeedReader { public class Noticia { public string Titulo { get; set; } public string Descripcion { get; set; } public string Enlace { get; set; } public string Imagen { get; set; } } } |
Leer un XML en Windows Phone 8.0
Para hacerlo en Windows Phone 8 vas a usar la clase WebClient que es la encargada de establecer la conexión e interpretar la información. Para ello, el código es el siguiente dentro del método sobre escrito OnNavigatedTo.
protected override void OnNavigatedTo(NavigationEventArgs e) { base.OnNavigatedTo(e); WebClient lectorFeeds = new WebClient(); lectorFeeds.OpenReadCompleted += lectorFeeds_OpenReadCompleted; lectorFeeds.OpenReadAsync(new Uri(http://aminespinoza.com/feed/)); } |
El objeto de tipo WebClient necesita establecer un manejador de eventos para su método OpenReadCompleted y después invocar al método OpenReadAsync para que puedas acceder a la información del feed. En el manejador de eventos de este objeto, haz lo siguiente.
void lectorFeeds_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e) { if (e.Error == null) { Stream streamRecibido = e.Result; XDocument documentoXML = XDocument.Load(streamRecibido); HandleXmlInformation(documentoXML); } else { MessageBox.Show("Error fatal 0x04402: Tu feed tiene algún error"); } } |
Como siempre, primero la cautela de verificar si tienes o no un error es indispensable (si lo hay no olvides poner tu “profesional” mensaje de error ). Si no hay error asigna el resultado obtenido a un Stream y a su vez, este stream a un objeto de tipo XDocument, después puedes ver un método llamado HandleXmlInformation. Este método lo veremos al final puesto que no importa la plataforma, todo lo que está ahí es común entre las dos versiones.
Leer un XML en Windows Phone 8.1
En el caso de Windows Phone 8.1 gracias su plataforma WinRT las cosas son más breves y manejables. Usemos el mismo método OnNavigatedTo.
protected async override void OnNavigatedTo(NavigationEventArgs e) { HttpClient client = new HttpClient(); string responseResult = await client.GetStringAsync(new Uri("http://aminespinoza.com/feed/")); XDocument documentoXML = XDocument.Parse(responseResult); HandleXmlInformation(documentoXML); } |
Las cosas cambian desde el primer objeto, aquí usamos un objeto de tipo HttpClient y su método GetStringAsync, recuerda que los métodos asíncronos deben tener un prefijo await y el método que ejecuta este tipo de tareas debe ser de tipo async. Convierte el resultado a un elemento de tipo XDocument para que te sea mucho más simple realizar consultas usando LINQ. Checa que al final invocamos el mismo método que en 8.0, HandleXmlInformation.
Un método en común
Ya viste que ambas plataformas tienen una manera diferente de obtener información de la misma fuente y en el mismo formato, de hecho me encantaría aclarar que en el caso de 8.1 hay una clase llamada SyndicationFeed que puede servir para leer entradas de RSS pero la intención de utilizar HttpClient es que no solo puedes leer feeds sino XML de cualquier fuente y origen.
El método HandleXmlInformation es el siguiente:
private void HandleXmlInformation(XDocument documentoXML) { List<Noticia> coleccionNoticias = new List<Noticia>(); coleccionNoticias = (from n in documentoXML.Descendants("item") select new Noticia { Titulo = n.Element("title").Value, Enlace = n.Element("link").Value, Descripcion = n.Element("description").Value, Imagen = (n.Element("image") == null) ? "http://lorempixel.com/150/150/" : n.Element("image").Value } ).ToList(); lstNotas.ItemsSource = coleccionNoticias; } |
Lo que necesitas en este método es una lista de tipo Noticias y esta lista se va a llenar por medio de una consulta de LINQ que te permita obtener todos los elementos que te interesan de tu XML. Nota que en el caso de la propiedad de imagen estamos implementando un operador ternario que te permite considerar que si el valor esperado es nulo puedes asignarle un valor específico o de lo contrario asignarle el esperado.
De esta manera puedes obtener entonces el mismo resultado en las dos plataformas. De cualquier manera, si quieres ver la estructura completa de los códigos, puedes descargar la solución completa aquí.
Hola, muy buena guía para los que empiezan como yo. Ahora te hago una pregunta, si quiero rescatar datos de los que me arroja esta dirección http://cdn.kloveair1.com/Services/Broadcast.asmx/GetRecentSongsLimit?siteId=2&limit=1&RemoveTags=true mas que nada es para saber el «Title» y el «Artist» se podrá? así armo una lista de los artistas y temas que se escuchan de esa radio… espero tu respuesta atte.
Claro, aunque todo eso depende mucho más de la configuración del servicio y sus posibles consultas que de cualquier limitante técnica.
Me sirvió mucho tu aporte
Ahora ya lo pude aplicar en mi proyecto