[Windows Phone] Buscar por actualizaciones desde la propia App

WindowsPhoneStoreUpdateIntroducción

Al desarrollar aplicaciones tarde o temprano tendremos la necesidad de actualizarlas ya sea bien por necesidad, para corregir bugs, o bien para añadir nueva funcionalidad. En ambos casos, nuestro mayor interés es que la mayor cantidad de usuariosse actualice a la última versión. Sin embargo, esto no siempre sucede.

¿Por que?

Podemos arrojar varias posibles causas:

  • El usuario utiliza el móvil con internet de manera muy puntual.
  • No tiene la Store anclada al inicio y no se da cuenta de las actualizaciones.
  • No se preocupa de revisar las actualizaciones.
  • Directamente el usuario desconoce como realizar la acción.

Sin abrir la aplicación de la Store y sin tenerla anclada al inicio puede provocar que los usuarios tengan aplicaciones sin actualizar a la última versión, no disfrutando de mejoras y lo que es peor sufriendo bugs que incluso pueden estar resueltos en versiones posteriores.

Para mejorar esta situación podemos indicarle al usuario de la disponibilidad de una actualización disponible. Pero… ¿cómo detectamos desde nuestra aplicación de la existencia de una actualización?

Cimbalino al rescate

Cimbalino Windows Phone Toolkit es un completo conjunto de herramientas destinadas a ahorrarnos tiempo y esfuerzo al desarrollar aplicaciones para Windows Phone del que ya hablamos previamente. Entre el conjunto de posibilidades que nos brinda, nos ofrece un servicio llamado IMarketplaceInformationService que nos permite verificar la existencia de actualizaciones de la aplicación dentro de la misma. Vamos a crear una Aplicación de ejemplo para utilizar el Toolkit y poder verificar la existencia de actualizaciones:

Tras crear el proyecto, comenzamos añadiendo el Toolkit. Tenemos disponible Cimbalino en NuGet por lo que podemos instalarlo usando Nuget Package Manager.

En las referencias del proyecto hacemos clic derecho y seleccionamos la opción Manage NuGet Packages …

Ejemplo Cimbalino 01
Manage NuGet Packages …

En la ventana modal que nos aparece, en la parte superior derecha donde podemos realizar una búsqueda, buscamos por “cimbalino”:

Ejemplo Cimbalino 02

Seleccionamos el primero de los elementos y pulsamos el botón Install. Tras un breve periodo donde se procede a descargar e incluir las librerías en las referencias del proyecto, tendremos el siguiente resultado:

Ejemplo Cimbalino 03
Librerías instaladas y listas para usar

Ya con la librería instalada podemos continuar con nuestro objetivo. Comenzamos definiendo la interfaz del ejemplo. En nuestro caso colocaremos un botón en la interfaz para verificar la existencia de actualizaciones. Sin embargo, la verificamos se puede realizar perfectamente en el arranque de la aplicación.

<Button Content="Buscar Actualizaciones"/>

Le añadimos un comando a ejecutar al ser pulsado:

<Button Content="Buscar Actualizaciones" Command="{Binding ChechForUpdatesCommand}" Height="100" VerticalAlignment="Center"/>

En el ViewModel correspondiente a la interfaz contaremos con el comando:

private ICommand _chechForUpdatesCommand;

public ICommand ChechForUpdatesCommand
{
     get { return _chechForUpdatesCommand = _chechForUpdatesCommand ?? new DelegateCommand(ChechForUpdatesCommandDelegate); }
}

public void ChechForUpdatesCommandDelegate()
{

}

Para utilizar el servicio IMarketplaceInformationService en la acción de nuestro comando necesitamos inyectar el servicio. Los servicios asi como la propia ViewModel no se creará manualmente sino que se resolverá automáticamente en tiempo de ejecución por el contenedor de dependencia. En el contenedor utilizaremos Unity (proyecto Open Source de Microsoft) para soportar la inyección de dependencias:

public Container()
{
     _currentContainer = new UnityContainer();

     //Servicios
     _currentContainer.RegisterType<IMarketplaceInformationService, MarketplaceInformationService>();
     _currentContainer.RegisterType<IMessageBoxService, MessageBoxService>();
     _currentContainer.RegisterType<IMarketplaceDetailService, MarketplaceDetailService>();

     //Vistas
     _currentContainer.RegisterType<MainViewModel>(new ContainerControlledLifetimeManager());
}

En el punto de entrada de la ViewModel (el contructor) inyectaremos los servicios necesarios previamente registrados en el contenedor:

public MainViewModel(IMarketplaceInformationService marketplaceInformationService, IMessageBoxService messageBoxService,
IMarketplaceDetailService marketplaceDetailService)<br />
{
     _marketplaceInformationService = marketplaceInformationService;
     _messageBoxService = messageBoxService;
     _marketplaceDetailService = marketplaceDetailService;
}

Con el servicio disponible, verificaremos la versión de la aplicación (por reflection):

var data = new AssemblyName(Assembly.GetExecutingAssembly().FullName);
var currentVersion = data.Version;

Y la compararemos con la versión disponible en la Store:

Version updatedVersion;
Version.TryParse(node.Entry.Version, out updatedVersion);

Para obtener la versión de la Store utilizaremos el método GetAppInformation del cual también tenemos versión asíncrona del servicio MarketPlaceInformationService.

En el resultado obtenido por la petición podemos obtener una enorme cantidad de la información relacionada con la apliación publicada en la Store:

  • Título
  • Versión
  • Publicador
  • Icono
  • Fotos
  • Fecha de publicación
  • Puntuaciones

Por lo que el servicio puede ser utilizado para una enorme variedad de situaciones con información relevante del estado de la apliación en la Store.

Comparamos versiones, si la actual es superior a la de la Store, tenemos actualización disponible. Utilizamos el servicio MessageBoxService de Cimbalino para notificar al usuario:

if (updatedVersion > currentVersion
&& _messageBoxService.Show(Resources.AppResources.DownloadUpdate, Resources.AppResources.UpdateAvalaible, MessageBoxButton.OKCancel) == MessageBoxResult.OK)
{

}

Por último, si el usuario desea abriremos la Store directamente con la apliación para que solo tenga que pulsar un botón para actualizar. Para ello usaremos otro servicio de Cimbalino, MarketPlaceReviewService:

_marketplaceDetailService.Show(ProductId);

NOTA: Dado que la aplicación de ejemplo no esta en la Store, para este ejemplo hemos utilizado una aplicación ya publicada en la Store en concreto Dev Center que va por su versión 1.4.1312.4.

Fácil, ¿verdad?. Tenemos disponible el ejemplo realizado a continuación:

Más información

Cimbalino Windows Phone Toolkit

Cimbalino-Windows-Phone-ToolkitIntroducción

En el desarrollo de una aplicación tenemos que tener en cuenta muchos factores, su contenido, su diseñoo su usabilidad entre otros factores. Pero por debajo de todo eso hay una base aun mas importante, el código. Como desarrolladores tenemosque esforzarnos por realizar un código de calidad acompañado de test y realizando un esfuerzo en cumplir buenas practicas con el objetivo en mente de tener un código facilmente ampliable, fácil de testear e incluso porque no, fácil de portar a otras plataformas. Sin embargo, en el proceso a este fin nos encontramos con piedras innecesarias en el camino. En el desarrollo de una aplicación Windows Phone siguiendo elpatrón MVVM entre otras buenas prácticas nos encontramos con que el ApplicationBar no soporta bindings, el LongListSelector tampoco en su elemento seleccionado, etc.

¿Y si pudieramos tener las cosas más fáciles?

Cimbalino Windows Phone Toolkit

Con ese objetivo en mente llega Cimbalino. Es un completo conjunto de herramientas destinadas a ahorrarnos tiempo y esfuerzo al desarrollar aplicaciones para Windows Phone.

El Toolkit esta dividido en proyectos:

  • Cimbalino.Phone.Toolkit: Base del Toolkit, contiene los servicios base del patrón MVVM, converters, helpers y metodos extensores además de la bindable Application Bar.
  • Cimbalino.Phone.Toolkit.Background: Servicios para los background agents compatibles con MVVM.
  • Cimbalino.Phone.Toolkit.Camera: Servicios para acceder a la cámara compatibles con MVVM.
  • Cimbalino.Phone.Toolkit.Controls: Controles (se necesita el Windows Phone Toolkit).
  • Cimbalino.Phone.Toolkit.DeviceInfo: Servicios para acceder a la información del dispositivo compatibles con MVVM.
  • Cimbalino.Phone.Toolkit.Location: Servicios para utilizar la localización compatibles con MVVM.
  • Cimbalino.Phone.Toolkit.MediaLibrary: Servicios para acceder a la librería Media compatibles con MVVM.
  • Cimbalino.Phone.Toolkit.PhoneDialer: Servicios para acceder a las funciones del teléfono compatibles con MVVM.
  • Cimbalino.Phone.Toolkit.UserInfo: Servicios para acceder a la información del usuario compatibles con MVVM.

NOTA: El Toolkit es compatible con Windows Phone SDK 7.1.x y Windows Phone 8.0.

Instalando el Toolkit

El Toolki lo tenemos disponible en NuGet por lo que podemos instalarlo usando Nuget Package Manager.

En las referencias del proyecto hacemos clic derecho y seleccionamos la opción Manage NuGet Packages …

Ejemplo Cimbalino 01

Manage NuGet Packages …

En la ventana modal que nos aparece, en la parte superior derecha donde podemos realizar una búsqueda, buscamos por “cimbalino”:

Ejemplo Cimbalino 02

Buscando “cimbalino”

NOTA: La primera opción incluye el Toolkit al completo. Sin embargo, como podemos apreciar en la captura anterior, podemos descargar por partes, solo aquellos componentes que nos interesen.

Seleccionamos el primero de los elementos y pulsamos el botón Install. Tras un breve periodo donde se procede a descargar e incluir las librerías en las referencias del proyecto, tendremos el siguiente resultado:

Ejemplo Cimbalino 03

Librerías instaladas y listas para usar

Contenido

Acciones

  • BingMapsAction
  • BingMapsDirectionsAction
  • ClipboardAction
  • ConnectionSettingsAction
  • EmailComposeAction
  • Etc

Behaviors

  • ApplicationBarBehavior
  • MultiApplicationBarBehavior
  • SafeBehavior
  • Etc

Converters

  • BooleanToBrushConverter
  • BooleanToIntConverter
  • BooleanToStringConverter
  • BooleanToVisibilityConverter
  • NegativeBooleanConverter
  • Etc

Extensiones

  • ByteArrayExtensions
  • DependencyObjectExtensions
  • DispatcherExtensions
  • EnumExtensions
  • FrameworkElementExtensions
  • Etc

Helpers

  • ApplicationManifiest
  • MutexLock
  • NamescopeBinding
  • Etc

Servicios

  • AddressChooserService
  • ApplicationLifecycleService
  • ApplicationManifestService
  • ApplicationProfileService
  • ApplicationSettingsService
  • AsyncStorageService
  • BingMapsService
  • ClipboardService
  • ConnectionSettingsService
  • DeviceStatusService
  • EmailAddressChooserService
  • EmailComposeService
  • LauncherService
  • LockScreenService
  • MapDownloaderService
  • MapsDirectionsService
  • MapsServices
  • MarketplaceDetailService
  • MarketplaceHubService
  • MarketplaceReviewService
  • MarketplaceSearchService
  • MessageBoxService
  • NavigationService
  • PhoneNumberChooserService
  • SaveAppointmentService
  • SaveContactService
  • SearchService
  • ShareLinkService
  • ShareMediaService
  • ShareStatusService
  • VoiceCommandService
  • WebBrowserService

Lo utilizamos!

vamos a crear una Aplicación de ejemplo para utilizar y ver superficialmente las posibilidades del Toolkit:

Creamos un proyecto desde la plantilla más básica para concentrar nuestra atención en el Toolkit que nos ocupa en esta entrada.

El ApplicationBar de Windows Phone, desde sus orígenes, es un objeto que no deriva de la clase FrameworkElement. Esto quiere decir que no soporta estilos o plantillas pero lo que es más importante, tampoco soporta binding en sus propiedades. Esto provoca problemas al trabajar utilizando el patrón MVVM, no podemos acceder directamente a los comandos de la ViewModel establecida como DataContext de la página.

Del listado anterior de contenido ya hemos visto que hay behaviors para el ApplicationBar que nos ayudan a resolver este problema con suma facilidad.

Vamos a utilizar el behavior. Para utilizarlo, lo primero que debemos hacer es añadir dos namespaces en nuestra vista:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cimbalinoBehavior="clr-namespace:Cimbalino.Phone.Toolkit.Behaviors;assembly=Cimbalino.Phone.Toolkit"

A continuación, definimos el behavior:

<i:Interaction.Behaviors>
     <cimbalinoBehavior:ApplicationBarBehavior>
          <cimbalinoBehavior:ApplicationBarIconButton
               Text="{Binding LocalizedResources.Message, Source={StaticResource LocalizedStrings}}"
               IconUri="../Toolkit.Content/ApplicationBar.Check.png"
               Command="{Binding ShowMessageCommand}"/>
          <cimbalinoBehavior:ApplicationBarBehavior.MenuItems>
               <cimbalinoBehavior:ApplicationBarMenuItem
                    Command="{Binding ShowMessageCommand}"
                    Text="{Binding LocalizedResources.Message, Source={StaticResource LocalizedStrings}}"/>
          </cimbalinoBehavior:ApplicationBarBehavior.MenuItems>
     </cimbalinoBehavior:ApplicationBarBehavior>
</i:Interaction.Behaviors>

NOTA: El behavior puede aplicarse directamente a un PhoneApplicationPage o a su elemento LayoutRoot (principal) para conseguir una ApplicationBar bindeable permitiendo mantener la consistencia en el patrón MVVM.

Podemos además de bindear el comando a ejecutar al pulsar el botón, los textos e incluso una propiedad para controlar la visibilidad.

El comando a ejecutar a su vez puede aprovechar cualquiera de los servicios que vimos previamente en el listado anterior. En nuestro ejemplo, bastará con añadir la dependencia en nuestro Ioc:

_container.RegisterType<IMessageBoxService, MessageBoxService>();

Definirlo en el constructor de nuestra ViewModel:

private readonly IMessageBoxService _messageBoxService;

public MainViewModel(IMessageBoxService messageBoxService)
{
     _messageBoxService = messageBoxService;
}

Y por último, utilizarlo directamente:

private ICommand _showMessageCommand;

public ICommand ShowMessageCommand
{
     get { return _showMessageCommand = _showMessageCommand ?? new DelegateCommand(ShowMessageCommandDelegate); }
}

public void ShowMessageCommandDelegate()
{
     _messageBoxService.Show(Resources.AppResources.Cimbalino);
}

Como hemos podido ver a lo largo del artículo, Cimbalino es un completo Toolkit destinado a acelerar y facilitar el desarrollo de aplicaciones Windows Phone. Muy buenas implementaciones de una gran cantidad de acciones, helpers, behaviors, etc. que os recomiendo probar. Podéis descargar el ejemplo realizado del siguiente enlace:

Como hemos podido ver a lo largo del artículo, el Toolkit es bastante amplio ofreciendo una cantidad de opciones muy interesantes permitiendo realizar y resolver tareas muy diversas. Retomaremos en futuras entradas este Toolkit para ver como notificar de actulizaciones de la aplicación publicada entre otros aspectos de interes.

Permaneced atentos!

Más información