[Material] Microsoft Tech Summit

El evento

El pasado 05 y 06 de Octubre, en el Palacio Municial de Congresos de Madrid tenía lugar el Microsoft tech Summit 2016, un evento donde se daban cita clientes, partners y desarrolladores de tecnologías Microsoft.

Microsoft Tech Summit
Microsoft Tech Summit

Con 10 Tracks organizados en diferentes categorías, varias deceneas de sesiones, un par de talleres y cientos de asistentes, un gran evento donde volver a ver a grandes amigos, conocer a otros nuevos, compartir y aprender mucho.

A continuación, una pequeña galería con algunos momentos del evento:

El material

Pude participar en el evento con una sesión en el track de Mobile Apps & Cross-Platform junto a un taller.

En la sesión me centré en dar a conocer todas las implicaciones y conceptos necesarios para desarrollar una aplicación UWP para Xbox One. Aspectos como la gestión del Gamepad, sonido o la adaptación a TV además de cómo adaptar la UI, sacar partido con efectos visuales y elementos 3D.

App UWP para Xbox One
App UWP para Xbox One

La presentación utilizada la tenéis disponible a continuación:

En cuanto a las demos técnicas realizadas, las tenéis disponible en GitHub:

Ver GitHub

Además de la sesión, por la tarde, disfrutamos de un divertido taller de 2,5h sobre Xamarin.

Realizamos paso a paso desde cero una aplicación meteorológica realizada con Xamarin.Forms y utilizando MVVM. Muy divertido!

Me gustaría terminar agradeciendo a Microsoft, sponsors, ponentes y asistentes por hacer el posible el evento. Ante la cantidad y calidad de sesiones, el networking, sorpresas, concursos y grandes momentos, no puedo terminar de otra forma que no sea…

¿Para cuándo el próximo?

Más información

[Tips and Tricks] Habilitar PlayReady en aplicación UWP para Xbox One

Introducción

Windows 10 ha llegado como la culminación en el viaje hacia la convergencia en el desarrollo entre plataformas Windows. Ahora hablamos de Apps Universales escritas una única vez con un código común tanto para la lógica de negocio como para la interfaz de usuario. Además, generamos un único paquete que mantendrá una interfaz consistente y familiar para el usuario pero adaptada a cada plataforma.

Podemos crear apps que funcionen en todo tipo de dispositivos como teléfonos, tabletas, portátiles, dispositivos IoT, Surface Hub e incluso Xbox One. Para ello tenemos las vías utilizadas hasta este momento, es decir, utilizando C# y XAML (o VB, C++, etc).

Ahora con la posibilidad no solo de desarrollar aplicaciones UWP para Xbox One sino además con la posibilidad de publicar la misma en la tienda, se convierte en una nueva vía llena de posibilidades.

Entre el conjunto de aplicaciones de interés para la plataforma, existen algunas categorías con especial peso como por ejemplo, las aplicaciones multimedia. Contenido en directo, bajo demanda o compartir contenido multimedia a nivel social son opciones habituales hoy día y con gran interés en una Xbox One conectada a una gran pantalla.

Te lanzas manos a la obra, con contenido adaptativo PlayReady utilizando un MediaElement y Microsoft Universal Smooth Streaming Client SDK, todo funciona correctamente pero a la hora de reproducir en la Xbox One…

MEDIA_ERR_SRC_NOT_SUPPORTED – 0x80070005

¿Qué ocurre?.

La clave, entrada en el archivo de manifiesto

Tranquilo, no estas haciendo nada incorrecto, para reproducir contenido PlayReady DRM en una aplicación UWP en Xbox One se requiere una DeviceCapability específica en el manifiesto.

Haz clic derecho sobre el archivo Package.appxmanifiest. Selecciona la opción abrir con editor XML. Dentro del conjunto de Capabilities debes añadir:

<Capabilities>
    <DeviceCapability Name="6a7e5907-885c-4bcb-b40a-073c067bd3d5" />
</Capabilities>

Y todo listo!.

Más información

[Windows 10 Anniversary Update] Novedades en x:Bind, bindings compilados

Link - 05Introducción

Data binding es un mecanismo mediante el cual podemos enlazar los elementos de la interfaz de usuario con los objetos que contienen la información a mostrar. Cuando realizamos data binding, creamos una dependencia entre el valor de una propiedad llamada target con el valor de otra propiedad llamada source. Donde normalmente, la propiedad target recibirá el valor de la propiedad source.

Es el mecanismo base que nos permite utilizar el patrón MVVM en nuestras Apps móviles logrando:

  • Nos permite dividir el trabajo de manera muy sencilla (diseñadores – desarrolladores)
  • El mantenimiento es más sencillo.
  • Permite realizar Test a nuestro código.
  • Permite una más fácil reutilización de código.

Sin embargo, además de toda la potencia mencionada teníamos ciertas limitaciones. Los errores de Binding no se producían en tiempo de compilación de la App además de tener diferentes mejoras relacionadas con el rendimiento. Limitaciones existentes hasta ahora…

Con la llegada de Windows 10 nos llegaba la posibilidad de crear bindings compilados en lugar de los bindings clásicos. Ya vimos previamente su uso, pros y contras en este artículo. Ahora, con la llegada del Anniversary Update nos llegan una gran cantidad de novedades relacionadas con el desarrollo que iremos desgranando poco a poco, entre las que se incluyen novedades en x:Bind.

¿En qué consisten?, ¿qué aportan?

En este artículo vamos a centrarnos en el conjunto de novedades incluidas en el sistema de enlace a datos compilados en la actualización Anniversary Update.

Enlace a métodos

Previamente, desde la versión 1607 de Windows, {x:Bind} soportaba un evento como parte del enlace a datos.

Veamos un ejemplo. Vamos a crear una interfaz mostrando un listado de casas. La colección de casas:

private ObservableCollection<House> _houses;
 
public ObservableCollection<House> Houses
{
     get
     {
          if (_houses == null)
               LoadHouses();
 
          return _houses;
     }
}

Que cargaremos con sencillos datos locales:

private void LoadHouses()
{
     _houses = new ObservableCollection<House>();
 
     _houses.Add(new House
     {
          Name = "Home 1"
     });
     _houses.Add(new House
     {
          Name = "Home 2"
     });
}

La interfaz de usuario, un control ListView enlazado con un enlace compilado a la colección:

<ListView
     ItemsSource="{x:Bind Houses}"
     ItemTemplate="{StaticResource HouseDataTemplate}" />

En cuanto a la plantilla que define cada elemento del listado:

<DataTemplate
     x:Key="HouseDataTemplate"
     x:DataType="model:House">
     <Grid>
          <Grid.ColumnDefinitions>
               <ColumnDefinition Width="Auto" />
               <ColumnDefinition Width="*" />
          </Grid.ColumnDefinitions>
          <TextBlock 
               Text="{x:Bind Name}"
               x:Phase="1"
               VerticalAlignment="Center" />
          <Button 
               Grid.Column="1"
               Content="Click me!"
               Click="{x:Bind Click}" />
     </Grid>
</DataTemplate

Se utiliza x:Bind para enlazar las propiedades, estableciendo el tipo de los datos a enlazar mediante la propiedad x:DataType.

NOTA: Recuerda que x:Bind está fuertemente tipado.

¿Ves algo «raro»?. El botón incluido dentro de la plantilla enlaza el evento Click a «algo» llamado Click.

Hasta ahora no habíamos visto la definición de la entidad House:

public class House
{ 
     public string Name { get; set; }
 
     public void Click(object sender, RoutedEventArgs e)
     {
          Debug.WriteLine(string.Format("Clicked {0}!", Name));
     }
}

Ahora probablemente has deducido que ocurre. Se pueden realizar enlace a datos directamente a eventos. Se necesita en el evento:

  • No tener parámetros. Ejemplo void Click().
  • Coincidir los parámetros con los parámetros del evento. Ejemplo: void Click(object sender, RoutedEventArgs e).
  • O coincidir con los tipos base de los parámetros del evento. Ejemplo: void Click(object sender, object e).

Al pulsar el botón de cada plantilla, se desencadena el evento Click que tenemos disponible en la entidad.

El resultado:

Event Bindings
Event Bindings

Ahora, tras la actualización Anniversary Update, se da un paso más permitiendo enlazar con cualquier método sin necesidad de un converter. Las únicas condiciones que debe complir el método es que sea público y en caso de tener parámetros, facilitarlos. Una forma de:

  • Obtener conversión de valores avanzada.
  • Tener un enlace a datos que dependa de más de un parámetro.

Veamos un ejemplo. En algunos formularios donde hay contraseñas involucradas se ofrece feedback visual de la seguridad de la contraseña introducida. Vamos a mostrar una barra de color rojo, naranja o rojo dependiendo de la seguridad.

Tendremos una propiedad donde se enlazará la contraseña:

public string UserPassword { get; set; }

En la UI:

<ProgressBar 
     Background="Transparent"
     Foreground="{x:Bind PasswordStrengthBrush(Password.Password), Mode=OneWay}"
     Value="{x:Bind PasswordStrengthValue(Password.Password), Mode=OneWay}"
     Height="3"/>
<PasswordBox 
     x:Name="Password"
     PlaceholderText="Insert Password"      
     Password="{x:Bind UserPassword, Mode=TwoWay}" />

Un control PasswordBox encargado de capturar la contraseña (utilizando x:Bind), y en la parte superior un ProgressBar que mostrará más o menos recorrido y distintos colores dependiendo de la seguridad de la contraseña introducida.

Fíjate en el enlace a datos de Foreground y Value del PasswordBox. ¿Qué está pasando?.

Para modificar el color se enlaza a un método público llamado PasswordStrengthBrush que recibe como parámetro la contraseña (directamente accediendo a la propiedad Password del PasswordBox!).

En cuanto al valor, de nuevo, se hace un enlace a un método público llamado PasswordStrengthValue recibiendo como parámetro de nuevo la contraseña.

El primero de los métodos:

public SolidColorBrush PasswordStrengthBrush(string password)
{
     if (string.IsNullOrEmpty(password))
          return new SolidColorBrush(Colors.Transparent);
 
     int length = password.Length;
 
     if (length >= 3 && length < 6)
          return new SolidColorBrush(Colors.Orange);
     if (length >= 6)
          return new SolidColorBrush(Colors.Green);
 
     return new SolidColorBrush(Colors.Red);
}

Si la longitud de la contraseña es inferior a tres carácteres, se devuelve color rojo, si es ingerior a seis carácteres, color naranja, devolviendo color verde en caso de que la longitud de la contraseña sea superior a seis carácteres.

El segundo de los métodos:

public double PasswordStrengthValue(string password)
{
     if (string.IsNullOrEmpty(password))
          return 0;
 
     int length = password.Length;
 
     if (length >= 3 && length < 6)
          return 66;
     if (length >= 6)
          return 100;
 
     return 33;
}

Aumentará el progreso de la barra de progreso en base a la longitud de la contraseña.

El resultado:

Function Bindings
Function Bindings

En un escenario donde se necesite un enlace a datos en modo two-way, se debe tener un segundo método encargado de hacer la operación inversa. Esto se consigue utilizando la propiedad BindBack.

Conversiones implícitas

x:Bind añade soporte a conversiones implícitas de algunos tipos.

¿Cuántas veces has creado un BoolToVisibilityConverter o similar (inverso, con opacidad, etc.)?.

Ya no sería necesario!. Podemos tener propiedades de tipo bool:

public bool IsVisible { get; set; }
public bool IsNotVisible { get; set; }

Donde una es cierta y otra falsa:

IsVisible = true;
IsNotVisible = false;

Al enlazar desde la UI:

<TextBlock 
     Text="Visible"
     Visibility="{x:Bind IsVisible}"/>
<TextBlock 
     Text="No Visible"
     Visibility="{x:Bind IsNotVisible}"/>

Podemos enlazar la propiedad Visibility directamente con bindings compilados a las propiedades de tipo bool.

¿El resultado?

Conversiones implícitas
Conversiones implícitas

El esperado, se muestra el elemento visual enlazada la propiedad verdadera. Se realiza la conversión implícita de un tipo a otro.

Castings de valor explícito soportados

Al contrario que el sistema de enlace a datos clásico que hace uso de duck typing, validación semántica, para validar el enlace, los bindings compilados verifican en tiempo de compilación que los tipos de los datos proporcionados coinciden. O lo que es lo mismo, si el valor que se estan tratando de enlazar no tiene un casting implícito al tipo de la propiedad, no se puede realizar el enlace sin un converter.

Eso era hasta ahora. Al más puro estilo C#, podemos declarar casting explícitos en un binding compilado.

Si tenemos una propiedad de tipo object:

public object Element { get; set; }

Si al crear la instancia, se crea utilizando un tipo específico (en nuestro ejemplo se utilizan tipos básicos para simplificar el ejemplo, object y TextBlock):

Element = new TextBlock
{
     Text = "Cool"
};

En la UI:

<TextBlock 
     Text="{x:Bind ((TextBlock)Element).Text}"/>

El resultado:

Casting explícito
Casting explícito

Se hace el casting al tipo TextBlock y podemos acceder a sus propiedades, enlazamos al texto.

Tenéis el código fuente del ejemplo utilizado disponible en GitHub:

Ver GitHub

Interesantes novedades, algunas de ellas muy solicitadas. También se han añadido otro tipo de actualizaciones menores como el soporte a más tipos de datos, por ejemplo, acceder a un índice específico de un diccionario clave-valor. Sin embargo, nos hemos concentrado en las que mayor impacto directo pueden tener en el desarrollo del día a día.

Y a ti, ¿qué te parecen?, ¿cúal es tu novedad favorita?, ¿qué te gustaría que se añadiese?.

Más información

[Material XDev Madrid] WinObjc: De iOS a Windows y extendiendo Xamarin.Forms

El evento

El pasado 09 de Agosto, desde el grupo XDev en Madrid, se organizaba un evento veraniego centrado en desarrollo móvil multiplataforma, con temas como convertir aplicaciones de iOS a UWP o extender Xamarin.Forms, además de tener momentos para el networking y algun que otro detalle con los asistentes.

El material

Pude participar en el evento con dos sesiones.

En la primera de ellos, nos centramos en el Windows Bridge para iOS, WinObjC. Convertimos algunas aplicaciones iOS a UWP e incluso vimos como añadir características específicas de la plataforma Windows como el uso de Live Tiles.

En la segunda sesión, nos centramos en como extender Xamarin.Forms para poder acceder a características específicas de cada plataforma, crear nuevos controles o efectos con el objetivo de ofrecer la mejor experiencia posible en cada plataforma, aun compartiendo gran parte de la interfaz de usuario.

En cuanto a las demos técnicas realizadas, las tenéis disponible en GitHub:

Ver GitHub

Quisiera terminar añadiendo algunos agradecimientos. Gracias a todos los asistentes por asistir además de la constante participación con preguntas, en estas fechas y con tan poca antelación en el anuncio del evento es destacable; gracias a Dachi Gogotchuri por toda la ayuda en la organización y gracias a Liferay por sus increíbles instalaciones cediéndonos una sala. Nos vemos en la próxima!

Más información

[Evento XDev Madrid] WinObjc: De iOS a Windows y extendiendo Xamarin.Forms

600_449727003.jpegIntroducción

A finales del año pasado nació el grupo de usuario XDev en Madrid, grupo de desarrolladores multiplataforma de Madrid.

Aprovechando visita a la capital, ¿algo mejor que organizar un evento junto a un poco de coworking?

El evento

El evento tendrá lugar el próximo Martes, 09 de Agosto y contará con dos sesiones:

  • 19:00h – 20:00h – WinObjc: Cruzamos el puente desde iOS a Windows! ¿Tienes una aplicación iOS?, ¿quieres reaprovechar tus conocimientos y código Objective-C para acceder a la plataforma universal Windows?. En esta sesión conoceremos el Bridge de Windows para iOS, convertiremos algunas aplicaciones iOS a UWP e incluso veremos como añadir características específicas de la plataforma Windows como el uso de Live Tiles por ejemplo. ¿Te apuntas?
  • 20:00h – 21:00h – Profundizando y extendiendo Xamarin.Forms Xamarin.Forms es un framework que nos añade una capa de abstracción permitiendo desarrollar la interfaz de nuestras aplicaciones móviles multiplataforma una única vez, compartiendo el código de la UI. Veremos como crear aplicaciones con Xamarin.Forms además de centrarnos en cómo acceder a características propias de cada plataforma mediante la creación de servicios o Custom Renders.

Se realizará en Liferay en sus oficinas de Paseo de la Castellana, 280, 28046 Madrid.

¿Te apuntas?

Más información

[Material CartujaDotNet] Sevilla Windows REBUILD

El evento

El pasado 21 de Abril, desde el grupo CartujaDotNet, grupo de usuarios .NET de Sevilla, organizábamos el Sevilla Windows REBUILD. Un evento donde recopilamos algunas de las principales novedades a nivel de desarrollo en la plataforma Universal Windows además de tener momentos para el networking y algun que otro detalle con los asistentes.

Novedades desarrollo UWP presentadas en el BUILD
Novedades desarrollo UWP presentadas en el BUILD

El material

Pude participar en el evento con múltiples sesiones. Tras una breve introducción a la agenda del evento comenzamos viendo las últimas novedades introducidas en Visual Studio (VS 2015 Update 2 y VS 15) destinadas para el desarrollo de UWP. Novedades en el editor XAML o Editar y Continuar en XAML:

Continuamos utilizando Desktop App Converter (aka Project Centennial) viendo como convertir una App Win32 en UWP.

En la siguiente sesión nos centramos en el desarrollo de aplicaciones UWP para Xbox One. Vimos desde como activar cualquier Xbox One para el modo desarrollador hasta como adaptar nuestras aplicaciones para ofrecer la mejor experiencia posible (gestión del gamepad, foco, TV safe area o sonidos).

En cuanto a las demos técnicas realizadas, las tenéis disponible en GitHub:

Ver GitHub

Quisiera terminar añadiendo algunos agradecimientos a Josué Yeray por participar junto a un servidor en las sesiones y por supuesto, muchas gracias a todos los asistentes.

Más información

Desktop App Converter, de Win32 a UWP

BridgeIntroducción

Llegar a Windows es mucho más sencillo que nunca. Si tienes una web, si tienes una App en iOS e incluso si partes de una App Win32, existen nuevas opciones destinadas a facilitar la llegada de esas Apps a Windows de la forma más sencilla posible. Si, hablamos de los Bridges presentados en el //BUILD del año 2015.

Un año después, en el marco del //BUILD 2016 se ha profundizado, conocido e incluso tenemos acceso a Project Centennial renombrado como Desktop App Converter, destinado a convertir Apps basadas en .NET y Win32 como Apps UWP. Además, permite el acceso a servicios o APIs UWP.

//BUILD 2016
//BUILD 2016

¿Quieres saber más el respecto?

En este artículo vamos a convertir una App Win32 a UWP utilizando Desktop App Converter paso a paso, desde la instalación de la herramienta hasta tener el paquete preparado, firmado y listo para distribución.

¿Qué es Desktop App Converter?

Herramienta disponible (pre-release) que nos permite llevar las aplicaciones de escritorio NET 4.6.1 o Win32 a la plataforma universal Windows (UWP). Basado en una línea de comandos, que se puede ejecutar de forma desatendida o silenciosa, crea un paquete appx que puede ser instalado mediante el comando Add-AppxPackage de PowerShell.

Desktop App Converter
Desktop App Converter

El convertidor utiliza una imagen limpia del sistema (disponible junto al convertidor) para utilizar una versión totalmente limpia del mismo y capturar cualquier entrada de registro, rutas de archivos, etc. y empaquetarlo todo en un paquete appx con su archivo de manifiesto correspondiente.

Las principales características son:

  • Permite convertir Apps Win32 a UWP.
  • Mantener y reutilizar la investigación y desarrollo invertida en la aplicación Win32.
  • Poder añadir y utilizar APIs UWP (Tiles, etc).
  • Utilizar la Windows Store y también poder monetizar la aplicación utilizando esta vía.

Preparación del entorno

Comenzamos descargando y preparando la herramienta pero antes incluso de descarga, repasemos los prerequisitos de hardware y software. Necesitamos una máquina de desarrollo con:

  • Procesador de 64 bits
  • Hardware-assisted virtualization
  • Second Level Address Translation (SLAT)

Mientras que a nivel de software debemos tener la versión 10.0.14316.0 o superior de Windows 10 Preview.

NOTA: Debemos tener la versión Enterprise de Windows para poder utilizar la herramienta. De momento, la versión pre-release disponible no funciona en la versión Pro.

Una vez revisados (y cumplidos) los requisitos necesarios realizamos la descarga de la herramienta. Podemos descargar Desktop App Converter desde el siguiente enlace.

Descargar Desktop App Converter
Descargar Desktop App Converter

Será necesario descargar:

  • DesktopAppConverter.zip
  • BaseImage-14316.wim

Tras extraer el archivo zip, estamos preparados para comenzar a preparar el entorno.

Comenzamos abriendo una ventana de PowerShell con privilegios de administrador.

Comenzamos modificando las preferencias de las políticas de ejecución de PowerShell evitando bloqueos o mensajes de alerta.

Set-ExecutionPolicy bypass
Set-ExecutionPolicy bypass
Set-ExecutionPolicy bypass

A continuación realizamos el setup de la herramienta con la siguiente línea:

.\DesktopAppConverter.ps1 -Setup -BaseImage .\BaseImage-14316.wim

NOTA: Debemos asegurarnos de navegar a la carpeta correspondiente donde hemos descomprimido la herramienta. Dependiendo de la elegida, la línea anterior puede cambiar ligeramente.

Llegados a este punto tenemos todo lo necesario para comenzar a utilizar la herramienta, es decir, para convertir Apps Win32 a UWP.

De Win32 a UWP!

El uso de la herramienta, como hemos comentado previamente, se realiza vía línea de comandos contando con gran cantidad de opciones:

DesktopAppConverter.ps1
-ExpandedBaseImage <String>
-Installer <String> [-InstallerArguments <String>] [-InstallerValidExitCodes <Int32>]
-Destination <String>
-PackageName <String>
-Publisher <String>
-Version <Version>
[-AppExecutable <String>]
[-AppFileTypes <String>]
[-AppId <String>]
[-AppDisplayName <String>]
[-AppDescription <String>]
[-PackageDisplayName <String>]
[-PackagePublisherDisplayName <String>]
[-MakeAppx]
[-NatSubnetPrefix <String>]
[-LogFile <String>]
[<CommonParameters>]

Tendremos parámetros obligatorios:

  • -ExpandedBaseImage: Ruta absoluta a la imagen base.
  • -Installer: Ruta a la aplicación Win32.
  • -InstallerArguments: Lista de parámetros separados por comas. Este parámetro es opcional si usamos un msi. Nos permite configurar sistema de logs, instalación silenciosa, etc.
  • -Destination: Ruta del paquete appx resultante.
  • -PackageName: El nombre que identifica el paquete.
  • -Publisher: Nombre del publicador incluido en el paquete.
  • -Version: Versión del paquete.

y otros opciones que pueden sernos de utilidad según el caso (por ejemplo, modo verboso). Podemos acceder vía línea de comandos a la ayuda de la herramienta en todo momento:

get-help .\DesktopAppConverter.ps1 -detailed

De modo que, convertir una aplicación Win32 llamada App.exe a una App UWP llamada «App» con versión 0.0.0.1 y publicador jsuarez serían tan sencillo como:

.\DesktopAppConverter.ps1 -Expanded C:\ProgramData\Microsoft\Windows\Images\BaseImage-14316 
–Installer C:\DesktopAppConverter\App.exe -InstallerArguments "/S" -Destination "C:\DesktopAppConverter\Output" 
-PackageName "App" -Publisher "CN=jsuarez" -Version 0.0.0.1 -MakeAppx -Verbose

Ejecutando el script en modo verboso en todo momento tenemos feedback del proceso (repaso de requisitos, conversión de rutas, registro,  preparación del manifiesto, etc):

Proceso de conversión
Proceso de conversión

Una vez terminado el proceso, en la carpeta de salida:

El resultado
El resultado

NOTA: Los paquetes generados por ahora sólo se pueden desplegar en sistemas x64.

Firmar el paquete

Para distribuir el paquete utilizaremos el comando Add-AppxPackage disponible en PowerShell. Para poder distribuirlo, el paquete debe estar firmado.

Para firmar el paquete, comenzaremos creando un certificado temporal utilizando la herramienta MakeCert. Abrimos una nueva ventana del símbolo del sistema de VS:

Símbolo del sistema de VS
Símbolo del sistema de VS

Bastará con escribir:

MakeCert.exe -r -h 0 -n "CN=jsuarez" -eku 1.3.6.1.5.5.7.3.3 -pe -sv myCert.pvk myCert.cer

Nos pedirá una contraseña:

Creando certificado
Creando certificado

A continuación, utilizamos Pvk2Pfx para generar el archivo pfx a utilizar para firmar el paquete:

pvk2pfx.exe -pvk myCert.pvk -spc myCert.cer -pfx myCert.pfx

Por último, utilizando Signtool para firmar el paquete:

signtool.exe sign -f myCert.pfx -fd SHA256 -v "C:\DesktopAppConverter\Output\App.appx"

Todo listo!. Ahora tenemos nuestra App Win32 conertida a UWP y lista para su distribución.

Despliegue

Utilizaremos la línea de comandos Add-AppxPackage para instalar la App. Sin embargo, obtendremos un error si en la máquina no tenemos importado el certificado con el que se firmó la App.

Para importar el certificado:

  1. Clic derecho sobre el paquete de la App, Propiedades -> Firmas digitales.
  2. Seleccionamos la firma, ver detalles y a continuación, ver certificado.
  3. Instalar certificado.
  4. Elegimos la opción equipo local y el contenedor de personas de confianza.
  5. Completamos.
Instalando certificado
Instalando certificado

Todo listo!. Ahora si, podemos ejecutar la línea:

Add-AppxPackages "C:\DesktopAppConverter\Output\App.appx"

La App se instalará!

Otros detalles

Desktop App Converter por defecto captura información relacionada con su uso y se la envía a Microsoft con el objetivo de mejora continua. Si deseamos modificar el comportamiento podemos añadir el siguiente valor del registro:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\DesktopAppConverter

Añadiremos el valor DisableTelemetry con DWORD establecido a 1 para deshabilitar el envío de información. Para volver a habilitar bastará con establecer el valor a 0 o bien, eliminar la entrada del registro.

¿Y ahora qué?

Llegados a este punto conocemos la herramienta, sus posibilidades y podemos comenzar a sacarle partido. Sin embargo, aún podemos llegar mucho más lejos. Podemos hacer uso desde la aplicación de de APIs UWP como:

  • Live Tiles
  • Cortana
  • Notificaciones
  • Etc

Podemos migrar código, utilizar AppServices y mucho más!. En próximos artículos continuaremos profundizando en la herramienta viendo coo realizar alguna de estas acciones. Os espero en el próximo!

Mientras tanto, ¿cuáles son vuestras experiencias?, ¿qué os parece Desktop App Converter?. Recordar que cualquier tipo de duda, sugerencia o comentario la podéis dejar en los comentarios de la entrada.

Más información

[Evento CartujaDotNet] Windows //REBUILD

dateEl evento

Tras un //BUILD 2016 repleto de novedades, ¿algo mejor que tener varias sesiones con las novedades más destacadas relacionadas con el desarrollo en Windows?.

//BUILD 2016
//BUILD 2016

Desde CartujaDotNet estamos convencidos que tendremos una divertida tarde con por supuesto sesiones técnicas, pero además, regalos, networking y otras grandes sorpresas.

La agenda

Contaremos con la siguiente agenda:

  • 18:00h – 18:15h Bienvenida. Receopción y bienvenida de asistentes.
  • 18:15h – 18:30h Novedades en Visual Studio para desarrollo UWP.  ¿Desarrollas aplicaciones universales Windows?. En esta sesión veremos algunas de las últimas novedades introducidas en Visual Studio destinadas para el desarrollo de UWP. Novedades como Editar y Continuar en XAML, novedades en depuración, etc.
  • 18:30h – 19:00h Desktop App Converter: De Win32 a UWP!. Llegar a la Windows Store es ahora más asequible que nunca. Si has invertido tiempo, esfuerzo y conocimientos en el desarrollo de aplicaciones Win32, ahora utilizando Project Centennial  te explicamos como convertirla en UWP y aprovechar todas las nuevas posibilidades disponibles, nuevas APIs, la Windows Store, nuevas formas de monetización y mucho más.
  • 19:00h – 20:00h Creando aplicaciones UWP para Xbox One. Llego el momento, por fin, podemos crear aplicaciones universales windows para Xbox One. En esta sesión veremos desde como activar cualquier Xbox One para el modo desarrollador hasta como adaptar nuestras aplicaciones para ofrecer la mejor experiencia.
  • 20:00h – 21:00h Introducción al desarrollo para HoloLens. Con las herramientas, emulador y todo lo necesario, nada mejor que ver las posibilidades de desarrollo con HoloLens, ¿cierto?.

Una agenda completa repleta de grandes novedades de la mano de Josué Yeray y un servidor.

La fecha

El evento tendrá lugar el próximo Jueves, 21 de Abril de 18:00h a 21:00h. Tendremos cuatro sesiones técnicas abordando algunas de las principales novedades en el desarrollo en la plataforma Windows.

El lugar

El evento se celebrará en la ETS de Ingeniería Informática. Dirección detallada:

E.T.S. Ingeniería Informática – Universidad de Sevilla
Av. Reina Mercedes s/n
Sevilla Se 41012

ETS de Ingeniería Informática
ETS de Ingeniería Informática

Si a pesar de todo el contenido de la agenda te parece poco, contaremos también con alguna sorpresa y regalo a sortear entre los asistentes.

¿Te apuntas?

Más información

[Windows 10] Biometría de huellas dactilares

Finger PrintIntroducción

En muchos desarrollos móviles tenemos la necesidad de contar con seguridad para limitar su acceso. Cuando hablamos de seguridad lo primero que se nos viene a la mente es la autenticación. La autenticación habitual, es decir, con usuario y contraseña, requieren una serie de características como gestión de las credenciales, complejidad de la contraseña, recuperación, etc.

Con Windows 10 tenemos dos nuevas tecnologías destinidas a facilitar la gestión de la seguridad tanto para usuarios como para desarrolladores integrando la tecnologías en sus Apps. Estas tecnologías son:

  • Windows Hello
  • Microsoft Passport

Windows Hello

El primero de ellos es un framework biométrico que soporta:

  • Reconocimiento facial
  • Escaneo de Iris
  • Huella

NOTA: Windows Hello requiere de hardware específico como lector de huellas o sensor

Microsoft Passport

Microsoft Passport aporta un mecanismo de autenticación que reemplaza las clásicas contraseñas por una combinación del dispositivo  junto a un PIN definido por el usuario o bien datos biométricos aportados por Windows Hello.

Datos biométricos, uso de huellas dactilares

Nuestro objetivo en este artículo será revisar todas las posibilidades brindadas por UserConsentVerifier. Esta nueva clase introducida en Windows 10 nos permite comprobar la disponibilidad de dispositivo que permita realizar una verificación biométrica (huella dactilar).

En nuestro ejemplo, contaremos con una interfaz sencilla:

<StackPanel
     HorizontalAlignment="Center"
     VerticalAlignment="Center">
     <Button 
          Content="Check UserConsent Availability" 
          Command="{Binding AvailabilityCommand}" />
     <TextBlock 
          Text="Request UserConsent Verification"
          Margin="0,24,0,0"/>
     <TextBox 
          PlaceholderText="Insert Message..."
          Text="{Binding Message, Mode=TwoWay}"/>
     <Button 
          Content="Request UserConsent Verification" 
          Command="{Binding VerificationCommand}"
          IsEnabled="{Binding IsUserConsentAvalaible}"/>
</StackPanel>

Un primer botón que nos indique la disponibilidad de dispositivo que permita realizar una verificación biométrica mientras que el segundo nos permitirá realizar la verificación del usuario con los datos biométricos.

Ambos botones contarán con un comando asociado en la ViewModel. El primero:

private ICommand _availabilityCommand;       

public ICommand AvailabilityCommand
{
     get { return _availabilityCommand = _availabilityCommand ?? new DelegateCommandAsync(AvailabilityCommandExecute); }
}

public async Task AvailabilityCommandExecute()
{

}

Y el segundo:

private ICommand _verificationCommand;

public ICommand VerificationCommand
{
     get { return _verificationCommand = _verificationCommand ?? new DelegateCommandAsync(VerificationCommandExecute); }
}

public async Task VerificationCommandExecute()
{

}

Nada especial a destacar llegados aquí. Continuamos…

Detectar si contamos con lector de huellas

Para poder utilizar datos biométricos en nuestra aplicación debemos antes que nada verificar si el dispositivo cuenta con lector de huellas. Podemos utilizar el método UserConsentVerifier.CheckAvailabilityAsync para la verificación.

En el servicio:

public async Task<UserConsentVerifierAvailability> GetUserConsentAvailabilityAsync()
{
     UserConsentVerifierAvailability consentAvailability =
     await UserConsentVerifier.CheckAvailabilityAsync();
     
     return consentAvailability;
}

El resultado será un valor de la enumeración UserConsentVerifierAvailability. Los posibles valores de la enumeración son:

  • Available: Dispositivo de verificación biométrica disponible.
  • DeviceBusy: El dispositivo de verificación biométrica está realizando una operación y no está disponible.
  • DeviceNorPresent: No hay dispositivo de verificación biométrica.
  • DisabledByPolicy: Por directiva de grupo, la verificación biométrica esta deshabilitada.
  • NotConfiguredForUser: No hay dispositivo de verificación biométrica configurado por el usuario actual.

Desde la viewmodel de la aplicación utilizaremos el servicio para la verificación:

IsUserConsentAvalaible = await _userConsentVerifierService.CheckUserConsentAvailabilityAsync();

Hasta este punto tenemos lo necesario para detectar si contámos con la posibilidad de usar datos biométricos o no.

Solicitud de consentimiento

Llega el momento de usar datos biométricos. Tras verificar la disponibilidad del lector debemos pedir consentimiento utilizando el método UserConsentVerifier.RequestVerificationAsync.

En nuestro servicio:

public async Task<UserConsentVerificationResult> GetRequestUserConsentVerificationAsync(string message)
{
     UserConsentVerificationResult consentResult =
     await UserConsentVerifier.RequestVerificationAsync(message);

     return consentResult;
}

NOTA: Para que la autenticación con la huella funcione correctamente, el usuario debe habe registrado su huella previamente.

Desde la viewmodel, bastará con usar el método anterior:

var result = await _userConsentVerifierService.GetRequestUserConsentVerificationAsync(Message);

Como parámetro pasamos una cadena. Esta cadena se utilizará para mostrar un mensaje al usuario en la solicitud de comprobación biométrica. En cuanto al resultado, obtenemos un valor de la enumeración UserConsentVerificationResult:

switch(result)
{
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.Canceled:
          message = "Consent request prompt was canceled.";
          break;
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.DeviceBusy:
          message = "Biometric device is busy.";
          break;
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.DeviceNotPresent:
          message = "Biometric device not found.";
          break;
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.DisabledByPolicy:
          message = "Disabled by policy.";
          break;
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.NotConfiguredForUser:
          message = "No fingeprints registered.";
          break;
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.RetriesExhausted:
          message = "Too many retries.";
          break;
     case Windows.Security.Credentials.UI.UserConsentVerificationResult.Verified:
          message = "User verified.";
          break;
}

Los valores de la enumeración son:

  • Verified: Huella comprobada correctamente.
  • DeviceNotPresent: Dispositivo biométrico no disponible.
  • NotConfiguredForUser: No hay ningún dispositivo biométrico configurado por el usuario actualo.
  • DisableByPolicy: La directiva de grupo ha deshabilitado el dispositivo biométrico.
  • DeviceBusy: Dispositivo biométrico ocupado al encontrarse realizando una operación.
  • RetriesExhausted: Tras 10 intentos, la solicitud de comprobación original y todos los intentos han fallado.
  • Canceled: Cancelación de la operación.

Sencillo, ¿cierto?.

Si ejecutamos la aplicación en un Lumia con opción biométrica, como por ejemplo un Lumia 950XL, ofrecerá dos opciones de auenticación:

  • Escáner de Iris
  • Código PIN

Igual resultado obtendremos en un PC que cuente con RealSense. Sin embargo, si probamos en un dispositivo sin posibilidad de detección biométrica aun así nos permitirá la validación vía código PIN.

PIN Code
PIN Code

De forma evidente no es un mecanismo de autenticación biométrica pero si suficiente para cubrir las necesidades de la API.

Tenéis el código fuente disponible en GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información

[Tips and Tricks] Windows 10. Adaptar recursos por DPI de pantalla

Scale to Fit-02Introducción

Con Windows 10 los desarrolladores recibimos la culminación de un gran viaje en la convergencia entre las diferentes plataformas Windows. Ahora podemos desarrollar aplicaciones para gran diversidad de familias de dispositivos como móviles, PCs, tabletas, IoT y otros que están por llegar, compartiendo la mayor cantidad de código, con un mismo proyecto y paquete. Además, contamos con grandes nuevas características como Continuum en teléfonos que permite convertirlo en un PC utilizando Microsoft Display Dock o Miracast.

Sin embargo, hay un detalle claro y obvio. Si contamos con un mismo paquete para todos esos dispositivos diferentes…¿cómo adaptamos la experiencia para ofrecer la mejor opción adaptada posible?

Debemos adaptar la interfaz de usuario en cada familia de plataforma para lograr ofrecer la mejor experiencia posible adaptada a la perfección. Para ello, utilizamos:

  • AdaptiveTriggers
  • Nuevos controles como RelativePanel y/o SplitView
  • Detección de modos de interacción
  • Etc

Sin embargo, hay elementos vitales en la mayoría de aplicaciones, que no acaban recibiendo la atención que se merecen. Estoy hablando de las imagenes. La aplicación puede usar una imagen que se visualiza perfectamente en un teléfono pero…¿y si se usa la aplicación con Continuum en una pantalla con una resolución diferente (más elevada)?.

En este artículo, vamos a aprender como organizar y utilizar los recursos de la aplicación para que se utilicen y adapten por DPI.

DisplayInformation

La clase DisplayInformation cuenta con propiedades y eventos que nos permiten verificar y monitorear información relacionada con la pantalla física. Para monitorear detalles como cambios en DPI o la rotación podemos usar la clase DisplayInformation.

En nuestra interfaz vamos a mostrar la siguiente información:

<StackPanel
     Orientation="Horizontal">
     <TextBlock Text="Logical DPI:" />
     <TextBlock Text="{Binding LogicalDpi}" />
     <TextBlock Text="DPI" />
</StackPanel>

<StackPanel
     Orientation="Horizontal">
     <TextBlock Text="Scaling:" />
     <TextBlock Text="{Binding Scale}" />
     <TextBlock Text="%" />
</StackPanel>

De modo que, en la viewmodel bindeada definiremos dos propiedades:

private string _logicalDpi;
public string LogicalDpi
{
     get { return _logicalDpi; }
     set
     {
          _logicalDpi = value;
          RaisePropertyChanged();
     }
}

private string _scale;
public string Scale
{
     get { return _scale; }
     set
     {
          _scale = value;
          RaisePropertyChanged();
     }
}

Una para cada valor que deseamos mostrar en pantalla. Utilizaremos el método DpiChanged lanzado cada vez que la propiedad LogicalDpi se modifica, cuando cambian los píxeles por pulgada (PPI) de la pantalla.

private DisplayInformation _displayInformation;

_displayInformation = DisplayInformation.GetForCurrentView();

Tras obtener la información física actual de la pantalla utilizando el método GetForCurrentView nos suscribimos al evento DpiChanged:

_displayInformation.DpiChanged += _displayInformation_DpiChanged;

Cada vez que el evento se lanza, actualizamos la información mostrada en pantalla:

private void _displayInformation_DpiChanged(DisplayInformation sender, object args)
{
     DisplayInformation displayInformation = sender as DisplayInformation;

     UpdateDpi(displayInformation);
}

private void UpdateDpi(DisplayInformation displayInformation)
{
     if (displayInformation != null)
     {
          LogicalDpi = displayInformation.LogicalDpi.ToString();
          Scale = (displayInformation.RawPixelsPerViewPixel * 100.0).ToString();
     }
}

Mostramos los píxeles por pulgada lógica de la pantalla actual utilizando la propiedad LogicalDpi, mientras que para la escala utilizamos la propiedad RawPixelsPerViewPixel que indica el número de píxeles físicos (RAW) por cada  pixel mostrado (Layout). Para obtener la escala bastará con multiplicar el valor por cien.

NOTA: En este ejemplo utilizamos la clase DisplayInformation para mostrar información contextual relacionada con el escalado de imágenes utilizado. Sin embargo, utilizando propiedades como DiagonalSizeInInches podemos saber facilmente el tamaño en pulgadas de la pantalla y así adaptar la interfaz en consecuencia. Sumamente útil y sencillo combinado con el uso de AdaptiveTriggers personalizados.

Recursos por DPI

Para optimizar nuestra interfaz en cada posible dispositivo o condición, podemos facilitar diferentes assets para diferentes resoluciones y escalas. Cada dispositivo cuenta con una escala específica resultante de la densidad de píxeles física y la distancia de visión teórica.

La escala es utilizada por el sistema, que realiza una gestión de recursos para determinar que recurso es el más adecuado entre las opciones facilitadas por los desarrolladores en sus aplicaciones.

NOTA: Los teléfonos suelen tener una escala de entre 200 y 400 mientras que dispositivos conectados como monitores y TVs tiene valores de 100 y 150 respectivamente.

Ejemplos de escala
Ejemplos de escala

Añadiendo recursos por escala

Para soportar el uso de diferentes recursos dependientes de la escala, bastará con añadirlos de la forma adecuada. Contamos con dos formas diferentes para ello.

Por un lado, podemos sencillamente añadir el mismo recurso con diferentes tamaños utilizando la notación .scale-xxx dentro de la carpeta Assets:

Recursos por DPI
Recursos por DPI

Por otro lado, podemos añadir diferentes carpetas con el nombre de la escala, es decir, scale-xxx incluyendo como contenido los recursos.

Utilizando recursos por escala

En nuestra carpeta de Assets contamos con una imágen única llamada Picture-NoScale:

<Image
     Source="ms-appx:///Assets/Picture-NoScale.png"
     Height="100"
     Width="100"
     HorizontalAlignment="Left"/>

Con el código anterior, usaremos la misma (y única) imágen existente bajo cualquier condición. Si la escala es alta y requiere de recursos con mayor resolución, el resultado será una visualización borrosa de la misma. Proporcionamos una experiencia no idónea.

Contamos con múltiples opciones por escala del  recurso llamado Picture, bastará con utilizarlo ignorando scale-xxx de la ruta:

<Image
    Source="ms-appx:///Assets/Picture.png"
    Height="100"
    Width="100"
    HorizontalAlignment="Left"/>

Utilizando los recursos vistos previamente, donde en un caso usamos una imágen única bajo cualquier condición y en otro una adapada a diferentes escalas, el resultado es el siguiente:

Carga de Assets por DPI
Carga de Assets por DPI

Tenemos 192DPI con una escala de 200%. Podemos ver a simple vista que mientras que la primera imágen se visualiza pixelada, la segunda se aprecia con una calidad alta.

Sencillo, ¿cierto?

Tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordad que podéis dejar cualquier comentario, sugerencia o duda en los comentarios.

Más información