Extendiendo el código generado en Windows Phone App Studio

Introducción

Previamente ya habíamos hablado de Windows Phone App Studio, nueva herramienta online que permite crear aplicaciones de calidad para Windows Phone 8 en cuestión de minutos.Entre sus principales características hay muchas destacables:

  • Permite crear aplicaciones Windows Phone sin tener conocimientos de desarollo.
  • Las Aplicaciones se generan en código nativo.
  • Permite instalar directamente la Aplicación sin requerir cuentas extras de ningun tipo.
  • Permite compartir la Aplicación creada con amigos.

App Studio

Sin embargo, la característica principal del sistema, es que puedes descargar el código fuente
de la Aplicación. Esto permite extender el código fuente añadiendo
nuevas características. En esta entrada vamos a analizar la estructura y
técnicas utilizadas en el código generado asi como aprener como
extenderlo con facilidad.

¿Te apuntas?

Echemos un vistazo al código…

Una vez generamos nuestra Aplicación desde Windows Phone App Studio veremos una pantalla similar a la siguiente:

Descargar el código fuente

Desde este apartado podemos:

  • Instalar nuestra Aplicación en un dispositivo para probarla de manera fácil leyendo un simple código QR.
  • Compartir vía email nuestra Aplicación con amigos.
  • Descargar el paquete de publicación (el XAP ya empaquetado listo para publicar).
  • Y por último, podemos descargar el código fuente!

Descargamos el código fuente de nuestra Aplicación:

Descomprimimos y abrimos la solución (Solution.sln) en Visual Studio.

NOTA: El proyecto es una solución para Windows Phone 8 que requiere Visual Studio 2012.

De un primer vistazo a la estructura de la solución podemos ver que la solución esta organizada en diferentes proyectos:Estructura

WP8App: Este proyecto es la Aplicación Windows Phone 8 en si. Implementa el patrón MVVM junto a otras técnicas y buenas prácticas (Ioc, servicios, etc) de los que hablaremos con calma más adelante.
Entities: Entidades utilizadas en la Aplicación. Las entidades implementan una iterfaz BindableBase que es una implementación de la interfaz INotifyPropertyChanged.
Repositories: En este proyecto tenemos disponibles todos repositorios de información utilizados por la Aplicación.

Esta
separación de responsabilidades en proyectos independientes nos permite
extender con mayor facilidad cada una de las partes implicadas asi como
la creación de test unitarios que se encargen de asegurar la calidad y
funcionamiento de todo.

 

Profundizamos en la estructura del proyecto Windows Phone:

Lo primero que llama la atención a simple vista es la implementación del patrón MVVM en el proyecto. Model-View-ViewModel (MVVM) es un patrón de diseño de aplicaciones que permite desacoplar el código de interfaz de usuario del código que no sea de interfaz de usuario.

El patrón MVVM se compone de tres partes fundamentales:

La Vista (View):
Define las vistas de la aplicación, es decir, conjunto de controles,
layout, estilos, etc. Se nutre del vista-modelo utilizando su propiedad DataContext.
Los controles se configuran mediante propiedades expuestas por el
vista-modelo e interactuan mediante el uso de comandos. Todas las vistas
están situadas dentro de la carpeta View.
El Vista-Modelo (ViewModel):
Conjunto de clases que encapsulan la lógica de presentación. Implementa
propiedades y comandos a los que se asociará la vista. Controla la
interacción de la vista con el modelo. Todos los viewmodels están
organizados dentro de la carpeta ViewModel.
El Modelo (Model):
Conjunto de clases que encapsulan los datos de la aplicación junto a su
lógica de negocio. Validan el modelo de los datos aplicando reglas de
negocio. El modelo suele implementar las interfaces INotifyPropertyChanged y INotifyCollectionChanged
para notificar cambios en propiedades y colecciones. No deben
referenciar a la vista ni al vista-modelo. En nuestra solución, tenemos
los modelos dentro del proyecto Entities (recordar que implementan la interfaz) .

A vista de pájaro ya hemos analizado la estructura del proyecto, sin embargo, creo que merece la pena que pronfundizemos más.

Con
el objetivo en mente se poder extender y reutilizar el código en la
medida de lo posible, se evita añadir código específico de la plataforma
en los viewmodels. No podemos utilizar directamente APIs de Windows
Phone en nuestros viewmodels.

¿Porque?

Hay varios motivos
para ello. Por ejemplo, si queremos portar la Aplicación a Windows 8
utilizaremos una Portable Library. Los viewmodels son candidatos
perfectos para migrar a la clase portable pero no podemos hacerlo con
código específico de la plataforma.

¿Cómo lo conseguimos?

Las operaciones que necesitemos en nuestra aplicación que requieran acceder a las APIs de Windows Phone las implementaremos en servicios. Podemos encontrar los servicios en la carpeta Services del proyecto.

Dependiendo
de los extras y otro tipo de configuraciones aplicadas en el portal
durante el proceso de creación de la Aplicación, podemos contar con los
siguientes servicios:

DialogService. Lo utilizamos para mostrar notificaciones en nuestra aplicación mediante Messagebox.
LiveTileService. El nombre deja pocas dudas. Lo utilizamos para la gestión de tiles en la aplicación, crear y eliminar tiles secundarios.
NavigationService. Utilizamos el servicio NavigationService para realizar la navegación entre páginas.
ReminderService. Nos permite crear recordatorios.
ShareService. Nos permite compartir información (Lanzador EmailComposeTask).
LockScreenService. Nos permite modificar la imagen utilizada en la LockScreen.
SpeechService. Nos permite utilizar TTS en nuestra Aplicación.
WebBrowserService. Abre una URL en el navegador (Lanzador WebBrowserTask).

Los viewmodels implementan los servicios gracias al uso de Ioc (Inversion of Control) por DI
(Dependency Injection). Se crea un contenedor donde registramos todos
los servicios que vamos a utilizar junto a los viewmodels que utilizarán
las vistas y que accederán a los servicios utilizando interfaces.

Para ello, se utiliza Unity v2.1,
el contenedor IoC de Patterns & Practices. Contamos con un service
locator (ViewModelLocator) que utilizará el contenedor creado. Está
instanciado en App.xaml y se utiliza para que cada vista pueda acceder a
la instancia de su viewmodel correspondiente cada vez que lo necesite.
Los viewmodels a su vez  accederán a los servicios utilizando
interfaces.

Llegados a este punto y tras analizar la estructura y
técnicas utilizadas en el código generado de nuestra aplicación podemos
deducir que:

  • El código generado implementa el patrón MVVM y
    utiliza conceptos y buenas prácticas como Ioc, servicios o la
    abstracción de implementaciones gracias a interfaces creando un código de calidad, además facilmente extensible.
  • El
    código viene en líneas generables perfectamente preparado para
    implementar test con facilidad o utilizar Portable Library y migrar
    nuestra aplicación a otras plataformas.
  • Para enriquecer nuestras
    vistas se utilizan algunas de las herramientas más conocidas en el
    entorno de desarrollo Windows Phone como el Toolkit o MyToolkit. Para 
    facilitar la gestión de dichas librerías se incluyen paquetes NuGet.

Asi que, analizada la estructura del código generado, ¿que tal si lo extendemos?

Extendiendo el código

Manos a la obra. Vamos a extender el código de la Aplicación generada. Para probar las múltiples opciones a realizar, vamos a:

  • Modificar uno de los servicios ya existentes para modificar la implementación del mismo.
  • Añadir un nuevo servicio que añada nueva funcionalidad a al Aplicación.

Comenzamos modificando uno de los servicios existentes. Nos centramos por ejemplo en el servicio DialogService  que utilizamos para mostrar notificaciones en nuestra aplicación mediante Messagebox:

public class DialogService : IDialogService
{
public void Show(string message)
{
MessageBox.Show(message);
}

public void Show(string message, string caption)
{
MessageBox.Show(message, caption, MessageBoxButton.OK);
}
}

Contamos
con las librerías del Windows Phone Toolkit incluidas en el proyecto.
Por lo tanto, podemos extender el servicio utilizando un control más
versátil como el CustomMessageBox perteneciente al Toolkit. Para ello,
en la misma clase, añadimos la referencia necesaria para poder utilizar
el control:

using Microsoft.Phone.Controls;

Reemplazamos la lógica de cada método:


public void Show(string message)
{
CustomMessageBox messageBox = new CustomMessageBox()
{
Message = message
};

messageBox.Show();
}

public void Show(string message, string caption)
{
CustomMessageBox messageBox = new CustomMessageBox()
{
Caption = caption,
Message = message
};

messageBox.Show();
}

Fácil,
¿verdad?. Por supuesto, podemos añadir más métodos al servicio
(recordar en dicho caso incluirlas en la interfaz) permitiendo confgurar
el botón derecho, el botón izquierdo, el contenido del mensaje (en este
control tenemos muchas posibilidades como por ejemplo incluir hasta un
Pivot como contenido), etc.

De acuerdo, hemos modificado algo
bastante simple. ¿Que pasa si deseamos añadir nueva funcionalidad a la
ya existente?. No dista mucho de lo ya realizado. Vamos a añadir un
nuevo servicio. Una acción bastante común en Aplicaciones Windows Phone
que acceden a información alojada en un servidor suele ser cachear la
información. Para ello, una buena opción es utilizar el Isolated
Storage.

Como el acceso al Isolated Storage es una funcionalidad
específica de la plataforma… si, efectivamente, va a los servicios.
Creamos entonces un servicio llamado StorageService.

Creamos la interfaz que define al servicio:

public interface IStorageService
{
T Load<T>(string fileName);
bool Save<T>(string fileName, T data);
}

Como
podéis ver muy sencilla. Tendrá un método Load que pasado un  nombre de
achivo devolverá la información almacenada y otro método Save que
tendrá como parámetros el nombre del archivo junto a la información a
almacenar.

Implementamos la interfaz:

public class StorageService : IStorageService
{

}

Creamos la clase que implementa la interfaz:

public T Load<T>(string fileName)
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
if (!myIsolatedStorage.FileExists(fileName))
return default(T);

using (IsolatedStorageFileStream stream = myIsolatedStorage.OpenFile(fileName, FileMode.Open))
{
var xml = new XmlSerializer(typeof(T));
T data = (T)xml.Deserialize(stream);
return data;
}
}
}

public bool Save<T>(string fileName, T data)
{
try
{
using (IsolatedStorageFile myIsolatedStorage = IsolatedStorageFile.GetUserStoreForApplication())
{
using (IsolatedStorageFileStream fileStream = myIsolatedStorage.CreateFile(fileName))
{
var xml = new XmlSerializer(typeof(T));
xml.Serialize(fileStream, data);
}
}

return true;
}
catch
{
return false;
}
}

El siguiente paso necesario será el registrar este servicio en nuestro contenedor de Ioc:

_currentContainer.RegisterType<IStorageService, StorageService>();

Por último, podemos utilizar nuestro servicio en un viewmodel por ejemplo muy facilmente:

private IStorageService _storageService;

En el contructor instanciamos los servicios:

public TheTeam_AlbumViewModel(IDialogService dialogService, INavigationService navigationService,
ILockScreenService lockScreenService, ITheGuysCollection theGuysCollection,
IawardsCollection awardsCollection, IvideosDataSource videosDataSource,
IblogDataSource blogDataSource, IStorageService storageService)
{
_dialogService = dialogService;
_navigationService = navigationService;
_lockScreenService = lockScreenService;
_theGuysCollection = theGuysCollection;
_awardsCollection = awardsCollection;
_videosDataSource = videosDataSource;
_blogDataSource = blogDataSource;
_storageService = storageService;
}

Y lo podemos utilizar por ejemplo, al obtener una colección de elementos:

_storageService.Save<ObservableCollection<RssSearchResult>>("Blog_NewsListControlCollection", Blog_NewsListControlCollection);

De
esta forma podemos almacenar en el almacenamiento aislado la
información del servidor. Si el usuario vuelve inmediatamente a ver la
misma información pdríamos recueperar la existente en lugar de volver a
realizar la petición al servidor.

Podéis echarle un vistazo al código generado (asi como las extensiones realizadas) descargando el ejemplo disponible desde el siguiente enlace.

En definitiva, el tener acceso al código nativo nos permite extender el código a nuestras propias necesidades.

Conclusiones

El
código generado implementa el patrón MVVM y utiliza conceptos y buenas
prácticas como Ioc, servicios o la abstracción de implementaciones
gracias a interfaces creando un código de calidad que como hemos podido verificar es facilmente extensible.

En
las plantillas de Visual Studio para Windows Phone se está extendiendo
el uso del patrón MVVM junto a otras buenas prácticas. Que el código
generado por Windows Phone App Studio haga uso de todas las buenas
prácticas y recomendaciones en el desarrollo Windows Phone es un punto
positivo que permite no solo ayudar a cualquier usuario a crear su
Aplicación para Windows Phone sino contribuir también en el aprendizaje
en el desarrollo de la plataforma mostrando los beneficios de estas
técnicas desde el principio.

Más información

Windows Phone App Studio ya disponible!

Crear Aplicaciones

De eso se trata. El crear las mejores y más atractivas aplicaciones
móviles posibles. Al fin y al cabo cada entrada de este modesto blog
tiene como objetivo aportar un granito de arena en lo posible. Nos
esforzamos día a día en crear las mejores aplicaciones posibles. Sin
embargo, el tiempo, ese fatidico enemigo que nos acosa constantemente,
es un riesgo común a la hora de crear aplicaciones. Proyectos que se
escapan por no cubrir las necesidades de la aplicación en el tiempo
deseado, por no llegar económicamente a poder gestionarlo o simplemente
porque el cliente desea ver un prototipo inicial que no podemos costear.

¿Y si tuviesemos una herramienta que nos solucionase todos esos problemas?

No, la magia no existe, pero si que acaba de lanzarse el servicio Windows Phone App Studio que nos permite crear aplicaciones de calidad para Windows Phone 8 en cuestión de minutos!

App Studio

¿Qué es Windows Phone App Studio?

Imagina la posibilidad de
crear prototipos en cuestión de minutos y poder enseñarselos al cliente
directamente desde el teléfono, o crear la base de tu aplicación y luego
poder continuarla tu mismo, si continuarla tu mismo, porque una de las
características principales del servicio es que permite descarga el código fuente de la aplicación generada!

Windows
Phone App Studio es un servicio al que accedemos a un portal web. Desde
el portal podemos crear aplicaciones para Windows Phone 8 mediante un
simple asistente de solo cuatro pasos.

Una vez creada la aplicación podremos probarla directamente en el
teléfono con tan solo leer un código QR, compartir el enlace a la
aplicación con amigos o descarga el código fuente de nuestra aplicación.
El código fuente contiene toda la estructura del proyecto con los
recursos incluidos respetando las guías de estilo y diseño además de
cuidar buenas prácticas en la organización del proyecto utilizando MVVM,
Ioc, separación de la lógica propia del sistema en servicios, etc.
Profundizaremos en este punto un poco más adelante.

Suena interesante, ¿verdad?

Un Tour por Windows Phone App Studio

Vamos a realizar un pequeño Tour paso a paso creando nuestra propia aplicación. Comenzamos!

El primer paso, elegir si partimos desde cero o desde una plantilla:

¿Plantillas?

El concepto es fácil. Podemos buscar similitudes
en la creación de documentos Word. Podemos partir de un documento vacío o
utilizar cualquiera de las plantillas de documentos que nos vienen
incluidas para crear calendarios, cartas, etc.

En este caso,
podemos partir desde una aplicación vacía que no contendrá nada o
utilizar una de las múltiples plantillas con las que cuenta App Studio
que se adapte a nuestras necesidades.

En este caso he decidido realizar una aplicación sobre Channel 9,
fantástico portal con videos relacionados con tecnologías Microsoft.
Para ello partiré de una de las plantillas, concretamente la de “Video
Channels”:

Vemos la descripción de la plantilla asi como unas capturas que nos
muestran el resultado de la misma. Pulsamos en botón “Create App” y
comenzamos!

Primer paso, “1ºApp Information”, definir la información base de la aplicación:

  • Título: El título de la Aplicación. Se colocará en la cabecera de la Aplicación.
  • Descripción: Descripción de la Aplicación.
  • Icono: Icono de la Aplicación. Se utiliza en la cabecera de la Aplicación asi como en los Tiles.

Nótese
que cada cambio realizado en la configuración de la Aplicación tiene
reflejo sobre el simulador HTML situado en la parte derecha:

Primer paso

Todo listo, nada más que hacer aqui, pasamos al segundo paso, “2º Configure App Content”:

Segundo paso

Desde esta sección podemos gestionar todo el contenido
de nuestra aplicación. La aplicación (plantilla seleccionada) cuenta
con 5 secciones organizadas en formato Panorama en la Aplicación (cada
sección corresponde con un PanoramaItem). Dentro de cada sección contamos con un conjunto de páginas que se abastecen de uno o más datasources.

Los DataSources
de la aplicación los tenemos situados en la parte izquierda. Contamos
con diferentes tipos de datasources a utilizar en nuestras aplicaciones:

  • Estático: Datos gestionados por nosotros mismos que serán incrustados como recurso en nuestra aplicación.
  • AppStudio:
    Datos gestionados por nosotros mismos pero a diferencia de los
    anteriores se almacenan en la nube. No hace falta actualizar la
    aplicación para actualizar la información.
  • RSS: Datos obtenidos de una URL RSS.
  • YouTube: Datos obtenidos de una búsqueda realizada en YouTube mediante un parámetro.
  • HTML: Información en formato HTML.

Haciendo clic sobre uno de los datasources entramos en modo edición del mismo:

DataSource

Volviendo a la vista principal del segundo paso, vamos a gestionar las
secciones. En la parte superior izquierda contamos con botones que nos
permiten editar o eliminar las secciones existentes:

En nuestro ejemplo, eliminamos todas las secciones exceptuando “channel9” y “about”.

En la gestión de una sección podemos, cambiar el nombre de la sección además de poder añadir o quitar páginas:

NOTA: Por supuesto, podemos añadir nuevas secciones a nuestra aplicación. Contamos con cuatro tipos diferentes de secciones:

  • Collection: Sección que cuenta con un DataSource estático y nos añade por defecto un par de páginas formando un maestro-detalle.
  • RSS: Sección que cuenta con un DataSource RSS y nos añade por defecto un par de páginas formando un maestro-detalle.
  • YouTube: Sección que cuenta con un DataSource YouTube y nos añade por defecto un par de páginas formando un maestro-detalle.
  • HTML: Sección que cuenta con un DataSource HTML y nos añade por defecto una única página.

Además
de gestionar los datasources y las secciones, podemos gestionar las
páginas de una sección. Haciendo clic en una de las páginas de una
sección:

En la edición de páginas podemos modificar el título de la página, el
Layout de la página y entra en juego un concepto bastante versátil e
interesante, los Bindings. Cada Layout cuenta con un
conjunto de posibles valores que podemos vincular a cada uno de los
campos correspondientes a un elemento de nuestro DataSource.

En
definitiva, el segundo paso es el paso de mayor importancia del
asistente. Nos permite gestionar el contenido de nuestra aplicación.
Partimos creando una sección de un determinado tipo según el tipo de
información a utilizar. Esto nos crea por defecto un datasource y entre
una y varias páginas. Podemos gestionar múltiples secciones configurando
el Panorama principal de la Aplicación.

NOTA: Al
añadir sección se permite también añadir un Menu. NO siempre crearemos
aplicaciones tipo Panorama con n PanoramaItems por sección. Podemos
tener un simple menu, un Panorama con un menu, etc. Nos hemos centrado
para introducir App Studio en un caso simple.

Una vez configurado
el contenido de nuestra Aplicación, un conjunto de videos del canal
oficial de YouTube y una vista con Información acerca de Channel9,
continuamos al siguiente paso.

Tercer paso, “3º Configure App Style”, donde configuraremos principalmente la apariencia de la Aplicación:

Desde este paso del asistente gestionamos tres puntos importantes de nuestra Aplicación (organizados por pestañas):

  • style: Desde
    este apartado configuramos los parámetros que afectan a la apariencia
    general de la Aplicación, el color de la fuente, el color o imagen de
    fondo, el color del ApplicationBar…
  • tiles: Desde
    este apartado elegimos que tipo de plantilla utilizamos en nuestro Tile
    de Aplicación (Cycle, Iconic o Flip) además de configurar el contenido
    del mismo.
  • splash & lock: En este apartado elegimos que imagen de splash y de lock screen utilizaremos en caso necesario en nuestra Aplicación.

¿Tenemos la apariencia de nuestra Aplicación bien definida?. Pasamos al último paso, “4º Summary”:

En este paso se nos muestra un resumen de nuestra Aplicación antes de
generar la misma. Es momento de revisar que el número de secciones,
páginas y datasources encajan con lo que teníamos en mente. Además en
este punto tomamos una decisión importante.

¿Recuerdas las
plantillas que vimos al comienzo antes de comenzar?. Tenemos la
posibilidad de hacer nuestra aplicación pública. De este modo al resto
de usuarios de App Studio le aparecerá la misma como plantilla
contribuyendo con la comunidad permitiendo crear cada vez aplicaciones
más completas y atractivas.

Para generar la Aplicación basta con pulsar el botón “Generate”:

Tras unos breves segundos tendremos nuestra Aplicación generada:

Probando nuestra Aplicación en el teléfono!

Una vez tenemos
la Aplicación generada podemos probarla directamente desde el teléfono
móvil. El primer paso es instalar el certificado Windows Phone App Studio certificate. Lo podemos hacer escaneándo su código QR:

NOTA: Este certificado sólo lo tenemos que instalar una única vez.

Tras instalar el certificado, podemos leer el código QR de nuestra aplicación para proceder a su instalación.

El Dashboard

Segun
vayamos creando aplicaciones sería fantástico  contar con un historial
que nos permita visualizar que aplicaciones hemos realizado asi como
poder gestionarlas. De hecho, existe, se llama DashBoard:

Seleccionando una Aplicación podemos obtener información detallada de
la misma además de poder realizar múltiples acciones como editarla,
descargar el código fuente, instalarla, o eliminarla.

Más Información

<Greeting Title="Hola" Type="geeks.ms" />

Me siento tremendamente orgulloso de poder inaugurar este blog. Para aquellos que no me conozcáis, deciros que llevo tiempo publicando artículos en http://javiersuarezruiz.wordpress.com y que, gracias a Rodrigo Corral entre otros, puedo dar el salto a geeks.ms. Mis inquietudes se mueven por el mundo XAML, Windows 8 y Windows Phone principalmente por lo que la mayoría de artículos se centrarán en dicha temática. También escribiré algunos artículos de otras temáticas asi como intentar comunicar posibles eventos o lanzamientos que puedan ser de interés para la comunidad.

Para los antiguos usuarios de mi antiguo blog, comunicar que, a pesar de publicar los artículos de entrada en geeks.ms, haré crossposting de aquellas de interés para que aquél se mantenga activo.

Para terminar, espero que este blog esté a la altura de sus vecinos y poder ayudar en todo lo posible a la comunidad.

Gracias por vuestro tiempo.

Keep Pushing!