[Windows Phone] Integrando los servicios de Xbox Music

Xbox Music

Xbox Music es un servicio digital que cuenta con
más de 30 millones de canciones disponibles con aplicaciones disponibles
para Xbox 360, Windows Store, Windows Phone, IOS y Android.
Recientemente también tenemos disponible el servicio vía web desde la
siguiente URL: music.xbox.com

Cuenta
con las capacidades necesarias para realizar búsquedas por artista,
canción o álbum ademas de poder crear y guardar listas de reproducción o
escuchar música sin conexión a internet entre otras funcionalidades.

Los servicios de Xbox Music

Recientemente
Microsoft ha dejado disponible una API de Xbox Music basada en
servicios web RESTful que permite de una manera muy sencilla conectar
desde una página web o una aplicación con los servicios de música de
Xbox.

Mediante el uso de la API de Xbox Music podemos:

  • Obtener los detalles de un álbum, artista o canción.
  • Buscar cualquier álbum, artista o canción.
  • Obtener las canciones top.
  • Obtener la información relacionada con nuevos álbums.
  • Obtener imágenes de un artista.
  • Obtener la carátula de un álbum.
  • Etc.

Integrándo los servicios en nuestra App

Sin duda pinta bien y
nos abre un mundo de posibilidades en nuestras aplicaciones. Vamos a
integrar en nuestra aplicación los servicios de Xbox Music.

Para ello, lo primero que debemos hacer es obtener un API Key para poder tener acceso en la API. Accedemos a la siguiente URL: music.xbox.com/developer

Pulsamos el botón «Get Started» y realizamos la petición del API Key.

Tras obtener el API Key tendremos una suscripción activa al servicio Xbox Music:

Para poder desarrollar aplicaciones que utilicen los servicios de Xbox
Music debemos crear una aplicación. Nos dirigimos al apartado
desarrolladores y creamos una aplicación:

Lo único que necesitamos es indicar nuestro clientId. Tanto el
clientId como el clientSecret generado seran necesarios en nuestro
código para pdoer acceder al servicio.

Como solemos hacer, vamos a crear una Aplicación de ejemplo para utilizar y ver las posibilidades de Xbox Music:

Creamos un proyecto desde la plantilla más básica para concentrar
nuestra atención en Xbox Music. La API se basa en servicios Restful,
podríamos hacer peticiones web con las credenciales para realizar las
búsquedas que necesitemos con facilidad. Sin embargo, podemos trabajar
con los servicios de Xbox Music de una manera aun más fácil si cabe
gracias a un Wrapper disponible en NuGet creado por Robert McLaws.

El Wrapper lo tenemos disponible en NuGet por lo que podemos instalarlo usando Nuget Package Manager. Podemos instalarlo ejecutando la siguiente línea de comandos: Install-Package Xbox.Music -Pre

Tras
instalar la librería portable podemos comenzar a trabajar con ella.
Comenzamos por la interfaz. Vamos a realizar una búsqueda genérica en
Xbox Music obtiene los resultados posibles:

  • Artistas
  • Discos
  • Canciones

NOTA: Al escribir este artículo la librería alcanza la definición RC.

Vamos a añadir una simple caja de texto con un botón para permitir obtener todos los resultados posibles segun la búsqueda:

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Text="{Binding SearchParam, Mode=TwoWay}"/>
<Button Grid.Column="1" Content="Buscar" Command="{Binding SearchCommand}"/>
</Grid>

Al buscar los resultados los mostraremos en un LongListSelector.

RECUERDA:
El control LongListSelector es como un control ListBox avanzado que
puede mostrar dos listas, una  plana y otra agrupada. Ayuda a los
usuarios a navegar a través de largas listas, le permite saltar entre
las diferentes secciones de la lista mediante una rejilla que se
superpone a la lista cuando el usuario selecciona uno de los
encabezados.

Nuestro objetivo es mostrar la información
agrupada por sistema operativo. De esta forma el usuario podrá pulsar
sobre las cabeceras del LongListSelector (los distintos tipos que
obtenemos, si es un album, un artista o una canción) y así poder acceder
al conjunto de elementos pertenecientes a un grupo de manera rápida y
efectiva.

<phone:LongListSelector />

Con la interfaz definida, pasamos a la lógica de la aplicación.
Organizamos nuestra aplicación bajo el patrón MVVM. Comenzamos
definiendo el modelo de nuestra aplicación, lo que se mostrará en el
LongListSelector:

public enum XboxMusicItemType
{
Artist,
Album,
Track
}

public class XboxMusicItem
{
public string Title { get; set; }
public string Image { get; set; }
public string Link { get; set; }
public XboxMusicItemType Type { get; set; }
}

Simple. La propiedad fundamental es Type que marcará de que tipo es
el elemento, necesario para organizar los elementos en el
LongListSelector. Centrandonos en laViewModel, necesitaremos una
propiedad de tipo string donde recibir el texto introducido en el
TextBox por el usuario, un comando donde ejecutar la búsqueda del botón y
una propiedad de tipo colección donde volcar la información recibida.

Definimos una propiedad donde almenar el texto de búsqueda introducido por el usuario:

public string SearchParam
{
get { return _searchParam; }
set
{
SetProperty(ref _searchParam, value);
}
}

Definimos una colección de objetos XboxMusicItem:

public List<Group<XboxMusicItem>> Items
{
get
{
return _items;
}
set
{
SetProperty(ref _items, value);
}
}

Definimos el comando a ejecutar al pulsar el botón:

private ICommand _searchCommand;

public ICommand SearchCommand
{
get { return _searchCommand = _searchCommand ?? new DelegateCommand(SearchCommandDelegate); }
}

public async void SearchCommandDelegate()
{

}

Nos centramos en la lógica del delegado del comando:

_client = new MusicClient(ClientId, ClientSecret);
var result = await _client.Find(SearchParam);

Utilizamos el wrapper de Xbox Music para Windows Phone para acceder a los servicios. Creamos un objeto de tipo MusicClient
pasándole en el constructor el ClientId y el ClientSecret que obtuvimos
al registrar una nueva aplicación en el portal. Tenemos disponible el
método Find que espera una cadena por la que realizará una búsqueda de todos los resultados posibles en el servicio.

En
la colección obtenida tenemos un listado de discos, cantantes,
canciones con objetos internos de la librería. Cada uno de estos objetos
cuenta con una cantidad interesante de propiedades relacionadas con el
objeto en cuestión además de métodos para obtener otro tipo de
información. Asi podemos obtener entre otra información:

Álbum

  • Artistas relacionados
  • Fecha de publicación
  • Canciones Top
  • Artistas relacionados
  • Géneros
  • Canciones
  • Portada

Cantante

  • Artistas relacionados
  • Canciones Top
  • Artistas relacionados
  • Géneros
  • Foto

Canción

  • Álbum al que pertenece
  • Duración
  • Número de canción
  • Cantantes
var items = result.Albums.Items.Select(album => new XboxMusicItem
{
Title = album.Name,
Image = album.GetImage(100, 100),
Link = album.GetDeepLink(),
Type = XboxMusicItemType.Album
}).ToList();

items.AddRange(result.Artists.Items.Select(artist => new XboxMusicItem
{
Title = artist.Name,
Image = artist.GetImage(100, 100),
Link = artist.GetDeepLink(),
Type = XboxMusicItemType.Artist
}));

items.AddRange(result.Tracks.Items.Select(track => new XboxMusicItem
{
Title = track.Name,
Image = track.GetImage(100, 100),
Link = track.GetDeepLink(),
Type = XboxMusicItemType.Track
}));

IEnumerable<Group<XboxMusicItem>> groupList = from item in items
group item by item.Type into g
orderby g.Key
select new Group<XboxMusicItem>(g.Key.ToString(), g);

Items = groupList.ToList();

Accedemos a la colección obtenida de discos, cantantes, canciones y las añadimos a nuestra colección agrupandola por tipo.

Ya
solo falta preparar nuestro LongListSelector para mostrar la
información agrupada. Continuamos contruyendo la interfaz de usuario.
Nos centramos en el archivo MainPage.xaml.

Vamos a definir las
distintas plantillas que debemos utilizar en el LongListSelector y que
ya hemos analizado previamente. Comenzamos con la plantilla GroupHeaderTemplate que definirá el aspecto de las cabeceras de cada grupo:

<DataTemplate x:Key="XboxMusicGroupHeaderTemplate">
<Border Background="Transparent" Padding="5">
<Border Background="{StaticResource PhoneAccentBrush}" BorderBrush="{StaticResource PhoneAccentBrush}" BorderThickness="2" Width="462"
Height="62" Margin="0,0,18,0" HorizontalAlignment="Left">
<TextBlock Text="{Binding Type}" Foreground="{StaticResource PhoneForegroundBrush}" FontSize="24" Padding="6"
FontFamily="{StaticResource PhoneFontFamilySemiLight}" HorizontalAlignment="Left" VerticalAlignment="Center"/>
</Border>
</Border>
</DataTemplate>

La siguiente plantilla, ItemTemplate, define el aspecto de cada elemento de la lista:

<DataTemplate x:Key="XboxMusicItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Image Source="{Binding Image}" Stretch="UniformToFill" Width="100" Margin="10"/>
<TextBlock Grid.Column="1" Text="{Binding Title}" TextWrapping="Wrap" FontSize="24"/>
</Grid>
</DataTemplate>

Podemos definir ya el control LongListSelector:

Si compilamos y probamos podemos observar que algo no va bien… ¿que ocurre?

Al
pulsar sobre una de las cabeceras no ocurre nada. Debería de
superponerse una rejilla con cada uno de los grupos de modo que permitan
posicionar al usuario al inicio del grupo en la lista plana.

¿Cómo lo solucionamos?

Utilizamos la propiedad JumpListStyle para ello. Con esta propiedad indicaremos como se comporta el LongListSelector al pulsar cabeceras.

NOTA: Si no definimos la propiedad IsGroupingEnable a True la lista aparecería sin agrupar, al igual que veríamos en un ListBox.

Lo
primero que haremos será utilizar dos Converters disponibles en el SDK
para determinar fuente y fondo de cada grupo que aparecerá en la rejilla
que superpones al pulsar una cabecera (si aparece pero con otro color o
no, etc):

<phone:JumpListItemBackgroundConverter x:Key="BackgroundConverter"/>
<phone:JumpListItemForegroundConverter x:Key="ForegroundConverter"/>

A continuación, definimos el estilo JumListStyle:

<Style x:Key="XboxMusicJumpListStyle" TargetType="phone:LongListSelector">
<Setter Property="GridCellSize"  Value="480,113"/>
<Setter Property="ItemTemplate">
<Setter.Value>
<DataTemplate>
<Border Background="{Binding Converter={StaticResource BackgroundConverter}}" Width="480" Height="113" Margin="6">
<TextBlock Text="{Binding Type}" FontFamily="{StaticResource PhoneFontFamilySemiBold}" FontSize="24" Padding="6"
Foreground="{Binding Converter={StaticResource ForegroundConverter}}" VerticalAlignment="Center"/>
</Border>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>

De modo que finalmente nuestro LongListSelector quedaría así:

<phone:LongListSelector
Grid.Row="1"
Background=" Transparent"
IsGroupingEnabled="True"
LayoutMode="List"
ItemsSource="{Binding Items}"
JumpListStyle="{StaticResource XboxMusicJumpListStyle}"
GroupHeaderTemplate="{StaticResource XboxMusicGroupHeaderTemplate}"
ItemTemplate="{StaticResource XboxMusicItemTemplate}"/>

Podéis ver el resultado a continuación:

Podéis descargar el ejemplo realizado del siguiente enlace:

NOTA: Para probar el ejemplo necesitaréis introducir vuestro propio ClientId y ClientSecret.

Más información

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *