15044_8989_7

[Evento CartujaDotNet] De 0 a tu startup… sorteando los problemas?

El evento

En los tiempos que corren, no es fácil abrirse camino en un mundo tecnológico complejo, lleno de adversidades y competencia. Hacerlo con éxito, es todo un reto.

Somos conscientes de ellos, por ese motivo, desde CartujaDotNet organizamos un evento más mesa redonda donde Josué Yeray, MVP de Windows y cofundador de DevsDna nos mostrará todas las claves del camino a recorrer, papeles y requisitos a cumplir, detalles a tener en cuenta, consejos, filosofía a utilizar y muchos otros aspectos para iniciar tu startup.

Tras un repaso, recorrido y consejos, contaremos con una divertida mesa redonda donde entre todos trataremos aspectos como las claves, filosofías que triunfan y qu evitar, dudas, preguntas y mucho más.

La agenda

La agenda específica del evento será:

  • 18:00h – 19:30h: De 0 a tu startup… sorteando los problemas?
  • 19:30h – 20:00h: Mesa redonda

La fecha

El evento tendrá lugar el próximo Jueves, 04 de Mayo de 18:00h a 20:00h. Tendremos tiempo para sesión, mesa redonda y mucho más!

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

¿Te apuntas?

Más información

moscone-west-1024x576

[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

centennial_00

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

moscone-west-1024x576

[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

img_xamarin1-930x360

[Xamarin.Forms] Backgrounding y persistencia de datos

Save-01-WFIntroducción

En dispositivos móviles contamos con una aplicación en primer plano. Cuando cambiamos de aplicación, si el usuario vuelve a la anterior, normalmente las aplicaciones vuelven a la última pantalla en la que se encontraba el usuario, con los datos e información que el usuario dejo. Todo listo y preparado para continuar. Un detalle que parece trivial pero que hoy día es necesario y esperado en cualquier aplicación.

Como desarrolladores debemos conocer el ciclo de vida de las aplicaciones móviles, la gestión y persistencia de información y como aplicar todo ese conocimiento para otorgar la mejor experiencia posible al usuario en cada plataforma.

En este artículo, vamos a aprender como realizar la persistencia de información de la aplicación en el ciclo de vida de la misma en Xamarin.Forms.

Eventos ciclo de vida

En Xamarin.Forms contamos con la clase Application donde establecemos el punto de entrada de la aplicación además de contar con métodos virtuales que podemos sobreescribir para gestionar el ciclo de vida de la aplicación:

  • OnSleep: Este evento se lanza cuando la aplicación pasa a background.
  • OnResume: Lanzado cuando la aplicación se resume después de estar en background.
protected override void OnStart()
{
    Debug.WriteLine ("OnStart");
}
protected override void OnSleep()
{
    Debug.WriteLine ("OnSleep");
}
protected override void OnResume()
{
    Debug.WriteLine ("OnResume");
}

Properties Dictionary

Desde la llegada de Xamarin.Forms 1.3 tenemos a nuestra disposición Application.Current.Properties. Ideal para utilizar en la suspensión y reanudación de la aplicación. Estamos ante un Dictionary con un uso muy sencillo que se encarga automáticamente del almacenamiento de datos en local.

Guardar

Utilizando Application.Current.Properties bastará con crear una nueva clave y asignar el valor:

Application.Current.Properties ["value"] = 1;

Leer

Recuperamos el valor utilizando la clave:

if (Application.Current.Properties.ContainsKey("value"))
{
     var val = Convert.ToInt32(Application.Current.Properties["value"]);
}

NOTA: Importante resaltar que como con el trabajo de cualquier diccionario, debemos verificar previamente la existencia del valor dado la clave otorgada.

Eliminar

En caso de desear eliminar el valor, de nuevo utilizamos la clave:

if (Application.Current.Properties.ContainsKey("value"))
{
     Application.Current.Properties.Remove("value");
}

Detalles a tener en cuenta

Debemos tener en cuenta que:

  • El valor asignado a una clave solo se guardará cuando se realice la suspensión de la aplicación (método OnSleep()). Es importante tener este detalle en cuenta ya que ante un cierre inesperado o bien en depuración al parar la misma, no guardaremos el valor al no realizarse la suspensión.
  • Al trabajar con un diccionario podemos guardar practicamente cualquier cosa, incluso entidades de clases propias que se serializarán.
  • Con Xamarin.Forms 1.4 se añadió un método adicional llamado SavePropertiesAsync() que podemos utilizar para guardar programáticamente cualquier cambio.

Persistencia de datos en Apps Xamarin.Forms

Para probar la persistencia de información junto al ciclo de vida de la aplicación vamos a crear un ejemplo Xamarin.Forms sencillo donde tendremos un formulario básico y guardaremos y recuperaremos la información al suspender y reanudar la aplicación.

Creamos la interfaz básica a utilizar:

<Grid
    VerticalOptions="Start">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="100" />
      <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <Label Grid.Column="0" Grid.Row="0" Text="First Name" VerticalOptions="End" />
    <Entry Grid.Column="1" Grid.Row="0" Text="{Binding FirstName, Mode=TwoWay}" />
</Grid>

El resultado:

Nuestra UI
Nuestra UI

En la viewmodel la propiedad bindeada:

private string _firstName;

public string FirstName
{
     get { return _firstName; }
     set
     {
          _firstName = value;
          RaisePropertyChanged();
     }
}

En la clase Application contamos con los métodos para gestionar el ciclo de vida de la aplicación. Como hemos visto, contamos con el método OnSleep() lanzado cuando la aplicación pasa a segundo plano. En este punto accederemos a la propiedad FirstName bindeada a la UI de la viewmodel y la guardaremos utilizando Properties Dictionary:

Application.Current.Properties["FirstName"] = viewModel.FirstName;   

Cuando la aplicación se resume, se lanza el evento OnResume(). En este punto verificamos la existencia de la propiedad FirstName y en caso de existir, la asignamos en nuestra viewmodel:

if (Application.Current.Properties.ContainsKey("FirstName"))
{
     var firstName = (string)Application.Current.Properties["FirstName"];
  
     viewModel.FirstName = firstName;
}

Podéis acceder al código fuente directamente en GitHub:

Ver GitHub

Más información

FondoEventoXamarin

[Material SVQXDG] Sevilla Xamarin Dev Day

RDXWoY7W_400x400El evento

El pasado 06 de Abril, desde el grupo SVQXDG, desarrolladores Xamarin de Sevilla, organizábamos el Sevilla Xamarin Dev Day. Un evento donde tener hueco a sesiones técnicas, analizar y aclarar cualquier duda relacionada con los últimos anuncios del //BUILD 2016 además de tener momento para el networking y algun que otro detalle con los asistentes.

El material

En mi caso, pude participar con una sesión casi obligatoria donde repasábamos los cambios fundamentales anunciados en el pasado //BUILD como:

  • Xamarin incluido sin coste adicional en todas las versiones de Visual Studio.
  • Xamarin Core o Xamarin.Forms Open Source.
  • La integración de Xamarin Insights a HockeyApp.
  • Otros aspectos como el progreso de Xamarin Test Cloud, Xamarin University, etc.

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

Posteriormente, continuamos con una sobre de desarrollo con Xamarin.Forms, donde vimos todas las claves para adaptar las aplicaciones a tabletas.

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 y Marcos Cobeña por participar junto a un servidor en las sesiones y por supuesto, muchas gracias a todos los asistentes.

Más información

printer_wallpaper

[Windows 10] Imprimiendo desde nuestras Apps UWP

Print - 01Introducción

Con Windows 10 tenemos gran cantidad de novedades interesantes relacionadas con el desarrollo de aplicaciones empresariales. Desde el gran potencial de Continuum a novedades en la Store pasando por nuevas APIs para trabajar con datos biométricos, bluetooth, criptografía, etc. Entre todas las características que podríamos necesitar, brilla con luz propia la posibilidad de imprimir.

En este artículo vamos a centrarnos en las posibilidades disponibles en los namespaces Windows.Graphics.Printing y Windows.UI.Xaml.Printing.

Nuestra aplicación

Nuestro objetivo será crear una aplicación UWP que mostrará un listado de la compra permitiendo imprimir la misma.

Crearemos un nuevo proyecto UAP:

Nueva App UAP
Nueva App UAP

Añadimos las carpetas Views, ViewModels y Services además de las clases base necesarias para implementar el patrón MVVM de la misma forma que vimos en este artículo.

Comenzamos definiendo la vista de nuestro ejemplo:

<Grid>
     <Grid.RowDefinitions>
         <RowDefinition Height="*" />
         <RowDefinition Height="50" />
     </Grid.RowDefinitions>
     <StackPanel 
        x:Name="PrintableContent">
        <TextBlock 
             Text="Shopping List"
             FontWeight="Black"
             Margin="12"/>
         <ListView
             ItemsSource="{Binding Products}"/>
     </StackPanel>
     <Button 
        Grid.Row="1"
        Content="Print"
        HorizontalAlignment="Center"/>
</Grid>

Sencilla. Cuenta con un listado que mostrará el listado de productos a comprar además de un botón que tendrá como objetivo realizar la impresión de la lista. La lista se encuentra enlazada a una propiedad pública llamada Products:

private ObservableCollection<string> _products;
public ObservableCollection<string> Products
{
     get { return _products; }
     set
     {
          _products = value;
          RaisePropertyChanged();
     }
}

Una colección de cadenas que contendrá cada producto. Cargaremos una lista desde local para simplificar el ejemplo y centrar toda nuestra atención en la impresión.

private void LoadProducts()
{
     Products = new ObservableCollection<string>
     {
          "Milk",
          "Apples",
          "Water",
          "Chicken meat",
          "Coffee",
          "Yogurt",
     };
}

Si ejecutamos el ejemplo veremos:

Nuestro ejemplo
Nuestro ejemplo

Registro para imprimir

En nuestro ejemplo, donde utilizamos el patrón MVVM y otras buenas prácticas, vamos a crear un servicio de impresión lo más genérico posible con el objetivo de poder reutilizarlo de forma rápida y sencilla entre diferentes desarrollos.

El primer paso para poder imprimir desde nuestras aplicaciones pasa por el registro del contrato de impresión. Nuestra aplicación debe realizar este proceso en cada pantalla desde la que deseamos permitir imprimir. Sólo podremos registrar la vista activa por lo también debemos preocuparnos de un proceso en el que eliminar el registro. Si nuestra aplicación navega a una nueva vista de la que deseamos imprimir de una anterior registrada para la impresión, al salir de la previa debe eliminar el registro correctamente.

Para realizar las operaciones básicas de impresión entre las que se encuentra el registro debemos utilizar la clase PrintManager  disponible en el namespace Windows.Graphics.Printing. PrintManager lo utilizaremos para indicar que la aplicación desea participar en la impresión además de poder iniciar la misma programáticamente.

También utilizaremos la clase PrintDocument disponible en el namespace Windows.UI.Xaml.Printing. En esta clase contamos con los métodos y propiedades necesarias para establecer el contenido a enviar a la impresora.

Definimos dos variables con cada una de las clases anteriores en nuestro servicio:

protected PrintManager Printmgr;
protected PrintDocument PrintDoc;

Nos centrámos en el proceso de registro:

public virtual void RegisterForPrinting()
{
     PrintDoc = new PrintDocument();
     PrintDoc.Paginate += CreatePrintPreviewPages;
     PrintDoc.GetPreviewPage += GetPrintPreviewPage;
     PrintDoc.AddPages += AddPrintPages;

     Printmgr = PrintManager.GetForCurrentView();

     Printmgr.PrintTaskRequested += PrintTaskRequested;
}

Instanciamos las clases PrintManager y PrintDocument además de realizar la subscripción a los eventos necesarios.

Para realizar el registro del contrato de impresión desde nuestra ViewModel utilizando el servicio, lo inyectaremos vía constructor:

private IPrintService _printService;

public MainViewModel(IPrintService printService)
{
     _printService = printService;
}

Y utilizamos el método creado RegisterForPrinting:

_printService.RegisterForPrinting();

NOTA: Al salir de la vista debemos quitar la subscripción al contrato de impresión, es decir, todos los eventos a los que nos registramos durante el registro. Si contámos con una aplicación con múltiples vistas, sin elimimar la subscripción, si dejamos la vista y regresamos obtendremos una excepción.

El contenido a imprimir

Ya que tenemos lo suficiente para registrar el contrato de impresión, debemos establecer el contenido que deseamos imprimir. En nuestro ejemplo contámos con un listado de productos correspondientes a una lista de la compra que deseamos imprimir.

¿Cómo funciona?

protected UIElement PrintContent;

La clase UIElement es una clase base de la mayoría de elementos visuales en Windows Runtime. Podemos utilizar cualquier elemento visual derivado de esta clase para imprimir. Nuestro contenido de impresión será por lo tanto un UIElement.

Tenemos donde almacenar el contenido a imprimir, necesitaremos también la operación de impresión. Para ello, utilizaremos una instancia de la clase PrintTask, la operación de impresión, incluyendo el contenido.

protected PrintTask Task;

Cuando realizamos el registro del contrato de impresión, nos registramos a múltiples eventos entre los que destaca PrintTaskRequested. Este evento correspondiente al PrintManager será el primero en lanzarse cuando el usuario quiera imprimir y le mostremos la ventana con la previsualización del contenido.

protected virtual void PrintTaskRequested(PrintManager sender,
            PrintTaskRequestedEventArgs e)
{
     Task = e.Request.CreatePrintTask(PrintTitle, async sourceRequested =>
     {
          PrintTaskOptionDetails printDetailedOptions = PrintTaskOptionDetails.GetFromPrintTaskOptions(Task.Options);

          printDetailedOptions.DisplayedOptions.Clear();
          printDetailedOptions.DisplayedOptions.Add(StandardPrintTaskOptions.Copies);

          Task.Options.Orientation = PrintOrientation.Portrait;

          Task.Completed += async (s, args) =>
          {
               if (args.Completion == PrintTaskCompletion.Failed)
               {
                    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
                    {
                         Debug.WriteLine("Failed to print.");
                    });
               }
           };

           await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
           {
                sourceRequested.SetSource(PrintDoc?.DocumentSource);
           });
     });
}

En este evento, instanciamos PrintTask utilizando el método PrintTaskRequest.CreatePrintTask.

NOTA: Le podemos pasar una cadena de texto al método CreatePrintTask. Se mostrará el texto en el título de la ventana de previsualización del contenido a imprimir.

Tras crear la tarea de impresión, se verifica el número de páginas a imprimir. Se lanza el evento Paginate correspondiente a la interfaz IPrintPreviewPageCollection.

protected virtual void CreatePrintPreviewPages(object sender, PaginateEventArgs e)
{
     PrintDoc.SetPreviewPageCount(1, PreviewPageCountType.Final);
}

Este evento puede lanzarse en múltiples ocasiones. Cada vez que el usuario modifique parámetros de configuración en la vista de previsualización de la impresión, el evento se lanzará para ajustar el contenido.

NOTA: Hemos simplificado nuestro ejemplo añadiendo directamente una única página. Podemos definir y crear tantas páginas como sea necesario.

Cuando en la vista de previsualización se va a mostrar una página, se lanza el evento GetPreviewPage.

protected virtual void GetPrintPreviewPage(object sender, GetPreviewPageEventArgs e)
{
     PrintDocument printDoc = (PrintDocument)sender;
     printDoc.SetPreviewPage(e.PageNumber, PrintContent);
}

Sencillamente establecemos el contenido de previsualización al PrintDocument.

Por último, contámos con el evento AddPages del conjunto de eventos al que nos registramos al registrar el contrato de impresión.

protected virtual void AddPrintPages(object sender, AddPagesEventArgs e)
{
     PrintDoc.AddPage(PrintContent);

     PrintDoc.AddPagesComplete();
}

En este evento añadimos el contenido a añadir a la colección de páginas de PrintDocument, es decir, el contenido a enviar a la impresora.

Estableciendo el contenido

Tras repasar cada unos de los eventos que componen el proceso de impresión, ¿cómo añadimos contenido desde nuestra ViewModel?. En nuestro servicio:

public virtual void SetPrintContent(UIElement content)
{
     if (content == null)
          return;

     PrintContent = content;
}

Tenemos un sencillo método que nos permite establecer cualquier elemento de la interfaz derivado de UIElement como contenido.

Añadir contenido desde la ViewModel será muy sencillo:

_printService.SetPrintContent(GetPrintableContent());

Para añadir el contenido utilizamos un Helper que nos permite obtener un elemento específico de UI utilizando su nombre:

private UIElement GetPrintableContent()
{
     return VisualHelper.FindChild<UIElement>(
                Window.Current.Content, "PrintableContent");
}

El Helper hace uso internamente de la clase VisualTreeHelper.

Mostrar previsualización

Con el registro del contrato de impresión, preparación del contenido y todo lo necesario para poder imprimir, es hora de permitir la operación al usuario. En nuestr servicio, utilizaremos el método asíncrono ShowPrintUIAsync para mostrar una ventana modal al usuario con la previsualización del contenido, las opciones de impresión además de por supusto las opciones para completar o cancelar la impresión.

public async void ShowPrintUiAsync(string title)
{
     try
     {
          PrintTitle = title;

          await PrintManager.ShowPrintUIAsync();
     }
     catch (Exception e)
     {
          Debug.WriteLine("Error printing: " + e.Message + ", hr=" + e.HResult);
     }
}

Si en el momento de lanzar el método ShowPrintUIAsync la operación no es posible, se lanzará una excepción. Es importante capturar esta excepción y actuar en consecuencia, notificando al usuario.

Desde la ViewModel, utilizando nuestro servicio:

_printService.ShowPrintUiAsync("Print Sample");

La ventana de previsualización:

Previsualización de la impresión
Previsualización de la impresión

Además de la previsualización, podremos configurar las opciones de configuración. En estas opciones, además de configuraciones básicas como la impresora a elegir o el número de copias, podemos configurar orientación, modos de color y muchas otras opciones.

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

Hello

[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

messaging-clients-comparison

[Xamarin.Forms] Utilizando Messaging Center

Mail Next-WFIntroducción

En el desarrollo de aplicaciones móviles multiplataforma con Xamarin es habitual utilizar el patrón MVVM para separar la vista de la lógica de negocio de la aplicación. De esta forma, podemos conseguir objetivos claves fundamentales como:

  • 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.
  • Compartir más código.

Xamarin.Forms incluye un completo sistema de enlace a datos y servicio de dependencias que nos permite realizar una completa implementación del patrón con facilidad. Sin embargo, en ocasiones, necesitamos ciertas “piezas” que nos permitan solucionar problemas existentes manteniendo la arquitectura intacta. En ocasiones realizamos cambios en un elemento de una vista que afecta a otro elemento correspondiente de otra. En este caso, debemos notificar de una viewmodel a otra del cambio.

¿Cómo lo hacemos?

Mensajes

Si has desarrollado previamente utilizando el patrón MVVM utilizando (o no) un framework posiblemente hayas utilizado lo que se conoce como sistema de mensajes. Basicamente la mensajería de basa en el patrón de diseño publish/subscribe. Contamos con tres grandes protagonistas:

  • Mensajes: Información a enviar normalmente relacionada con la lógica de negocio.
  • Publicadores: Cuando un evento ocurre, ya sea un simple click de un botón o una lógica compleja, los publicadores toman la información a enviar y publican el mensaje.
  • Subscriptores: En el lado opuesto, tenemos a los subscriptores que esperan la publicación de un mensaje de un tipo específico para captarlo con toda la información enviada y actuar en consecuencia.

Messaging Center

Xamarin.Forms cuenta con MessagingCenter para permitir la comunicación entre viewmodels u otros componentes sin que tengan que tener referencias entre ambos utilizando el patrón publish/subscribe.

Para probar MessagingCenter vamos a crear una aplicación Xamarin.Forms sencilla donde tendremos dos vistas. La primera vista mostrará un mensaje y un botón además de suscribirse a un mensaje de cambio. El mensaje se modificará utilizando MessagingCenter mientras que el botón permitirá navegar a la segunda vista. Al navegar a la segunda vista se publicará el mensaje de modo que, al regresar a la primera vista el mensaje será modificado.

Definimos la interfaz de la primera vista:

<StackLayout Padding="10" Spacing="10">
     <Label Text="{Binding Info}" />
     <Button 
          Text="Navigate to Second View"
          Command="{Binding NavigateCommand}"/>
</StackLayout>

El resultado:

Nuestra interfaz
Nuestra interfaz

En la viewmodel correspondiente a la vista definimos la propiedad que utilizaremos para mostrar el mensaje:

public string Info
{
     get { return _info; }
     set
     {
          _info = value;
          RaisePropertyChanged();
     }
}

Y el comando que permitirá la navegación a la segunda vista:

private ICommand _navigateCommand;

public ICommand NavigateCommand
{
     get { return _navigateCommand = _navigateCommand ?? new DelegateCommand(NavigateCommandExecute); }
}

public void NavigateCommandExecute()
{
     _navigationService.NavigateTo<SecondViewModel>();
}

En la primera vista vamos a suscribirnos a un mensaje. En Xamarin.Forms contamos con MessagingCenter que cuenta con dos partes fundamentales:

  • Suscripción (Subscribe): Se suscribe a un mensaje concreto para lanzar una acción.
  • Envío (Send): Publica un mensaje para ser captado por suscriptores. Si no existiese ningún subscriptor, el mensaje es ignorado.

La clase MessagingCenter es una clase estática que cuenta con varias sobrecargas del los métodos Subscribe y Send.

Podemos subscribirnos a un mensaje simple con una cadena:

Xamarin.Forms.MessagingCenter.Subscribe<FirstViewModel>(this, "Change", (sender) =>
{
     Info = "Changed from Messaging Center";
});

La viewmodel de la primera vista se subscribe a un mensaje de tipo string con el mensaje “Change”.

Navegamos a la segunda vista:

Segunda vista
Segunda vista

En la viewmodel de la segunda vista procedemos a enviar un mensaje de tipo cadena con el valor “Change”:

Xamarin.Forms.MessagingCenter.Send(App.Locator.FirstViewModel, "Change");

Al regresar a la vista anterior, el mensaje ha cambiado con la lógica ejecutada en la subscripción del mensaje:

Mensaje recibido
Mensaje recibido

Sencillo, ¿cierto?

Pasar parámetros como argumento

Podemos pasar un argumento como parámetro del método Send:

MessagingCenter.Send(App.Locator.FirstViewModel, "Change", "Argument");

En la subscripción podemos capturar el parámetro de forma sencilla:

MessagingCenter.Subscribe<FirstViewModel>(this, "Change", (sender, arg) => {
    // Acceso a 'arg' para obtener el parametero
});

Podéis encontrar en GitHub el ejemplo de este artículo:

Ver GitHub

Recordad que cualquier duda o sugerencia la podéis dejar en los comentarios del blog.

Más información

Xamarin-Dev-Day-October-2015

[Evento SVQXDG] Sevilla Xamarin Dev Day

Xamarin LogoEl evento

En Sevilla, existen empresas y desarrolladores con un enorme talento utilizando Xamarin para sus desarrollos de Apps móviles. Con este crisol nació SVQXDG, o lo que es lo mismo, grupo de desarrolladores Xamarin de Sevilla. Es un grupo de usuario donde se busca tener un punto habitual de reunión para ayudar, compartir y aprender entre todos.

Continuamos con fuerza en el grupo organizando un nuevo evento completo con múltiples sesiones buscando cubrir múltiples aspectos relacionados con el desarrollo de aplicaciones Xamarin.

Tendremos la siguiente agenda:

  • 18:00h – 18:45h: Adaptar Apps Xamarin.Forms a teléfonos y tabletas. En esta sesión de la mano de Javier Suárez veremos como adaptar nuestras aplicaciones para otorgar la mejor experiencia posible en teléfonos y tabletas. Como adaptar vistas, tener vistas específicas, adaptar navegación o detectar DPIs y tamaño de pantalla serán algunos de los puntos que veremos.
  • 18:50h – 19:35h: Gestión de notificaciones Push en Apps Xamarin con Azure. Josué Yeray nos enseñará en esta sesión como usar notifications hubs de Azure para enviar notificaciones facilmente a cualquier plataforma. Veremos como funcionan las notificaciones push en cada plataforma así como implementarlas de forma sencilla.
  • 18:40h – 20:25h: Trucos y claves de App Xamarin hasta su llegada en la Store. Terminaremos el evento con una completa sesión de Marcos Cobeña en la que nos mostrará los detalles y claves a tener en cuenta en el desarrollo de una App Xamarin real ¡Buenos días! aro, desde su desarrollo hasta tenerla en la Store.

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 Ingeniería Informática
ETS Ingeniería Informática

La fecha

El evento tendrá lugar el próximo Miércoles, 06 de Abril de 18:00h a 20:30h. Tendremos tres sesiones de 45 minutos de duración cada una.

¿Te apuntas?

Más información