[Material] Codemotion 2015: Integración continua con Apps Xamarin

El evento

El pasado 27 y 28 de Noviembre, en la universidad San Pablo CEU, tenía lugar el Codemotion
2015. El mayor evento destinado a desarrolladores en España con más de
1900 desarrolladores, más de 30 comunidades técnicas y más de 130
sesiones técnicas.

Codemotion 2015

Codemotion 2015

Be an agent of chaos

El material

En el evento pude aportar mi granito de arena con una sesión sobre desarrollo con Xamarin donde vimos:

  • Como desarrollar aplicaciones móviles multiplataforma con Xamarin.
  • Creación de pruebas unitarias.
  • Pruebas de de interfaz con Xamarin UITests con Xamarin Test Recorder.
  • Test Cloud.
  • Integración continua.

Tenéis disponible la presentación utilizada a continuación:

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

Ver GitHub

Más información

Novedades en CartujaDotNet

Introducción

CartujaDotNet (@cartujadotnet)
es un grupo de usuarios .NET en Sevilla que lleva ya años realizando
interesantes charlas y eventos relacionados con las tecnologías
Microsoft.

CartujaDotNet

CartujaDotNet

Nuevo dominio

Para facilitar el acceso al grupo desde el inicio se buscó contar con
un dominio sencillo de recodar. Inicialmente utilizábamos el dominio cartujadotnet.es para facilitar el acceso al portal del grupo. Hemos modificado el dominio a www.cartuja.net. Buscamos facilitar una opción más sencilla, corta y lógica a la hora de recordar el acceso.

Meetup

Por otro lado, hasta ahora contábamos con un gran blog donde
añadíamos los eventos y quedadas organizadas por el grupo. La
experiencia de los últimos años nos han mostrado la necesidad de otras
opciones como:

  • Discuciones o encuestas para decisiones varias.
  • Ofertas de trabajo.
  • Recopilar el material de cada evento.
  • Aumentar opciones sociales, permitir libre comunicación entre miembros, recopilar fotos y videos de eventos y quedadas, etc.
  • Facilitar búsqueda de eventos.
  • Notificaciones.

Por estos motivos, pasamos el grupo a Meetup. CartujaDotNet estrena Meetup en este enlace:

www.meetup.com/es/Cartuja-NET/

Esperamos seguir realizando eventos y quedadas periódicas pero de
forma más social, recopilando materiales, con fotos y mayor cantidad de
detalles. También esperamos facilitar la comunicación y colaboración
entre miembros, ayudar a la comunidad con ofertas de trabajo y todo lo
posible que recaiga en nuestras manos.

Meetup CartujaDotNet

Meetup CartujaDotNet

Más información

Meetup: CartujaDotNet

[Tips and Tricks] DeviceFamily Adaptive XAML Tool

Introducción

Con la llegada del SDK de Windows 10 Preview tenemos la posibilidad de crear Apps Universales con un único binario
que funcione en múltiples plataformas. Es un paso importante pero que
conlleva realizar una acción que sera comun, diferenciar entre las
diferentes plataformas donde correrá dicho binario para poder adaptar la
interfaz de usuario. Con ese objetivo utilizamos entre otras opciones
los Adaptive Triggers de los que ya hemos hablado.

Sin embargo, en ocasiones la misma vista en diferentes dispositivos puede que sea totalmente diferente.

En estos casos podemos crear vistas diferentes por familias de
dispositivos. Tras añadir una vista de la forma habitual, creamos una
carpeta siguiente la siguiente nomenclatura:

  • DeviceFamily-[Family]

Donde Family es la familia del dispotivo para el que
deseamos sobrescribir la vista.Dentro de esta carpeta añadimos la vista
XAML deseada en esa plataforma.

NOTA: Añadimos la sobreescritura de la vista. Es
importante un detalle del fichero añadido, no añadimos code behind.
Esta vista utilizará el mismo code behind que la que teníamos
previamente.

DeviceFamily Adaptive XAML Tool

Gestionar carpetas o vistas por familia de dispositivo se vuelve aun más sencillo gracias a la extensión Device Family Adaptive XAML Tool creada por Olivier Matis.

Podemos hacer clic derecho sobre la solución para acceder a un menu
contextual llamado “Add single folder” para añadir carpeta de vistas
específica para una plataforma concreta. Además, haciendo clic sobre una
vista existente tendremos acceso a otro menu contextual “Add device
family XAML” que nos creará la vista XAML específica para la familia de
dispositivos seleccionada.

DeviceFamily Adaptive XAML Tool

DeviceFamily Adaptive XAML Tool

Sencillo pero extremadamente útil, ¿cierto?.

Más información

[Quedada SVQXDG] Novedades en Xamarin 4!

SVQXDG

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.

SVQXDG

SVQXDG

Xamarin 4

Aprovechando el lanzamiento de la iteración 4 de los productos de Xamarin, en nuestra próxima quedada, el próximo 02 de Diciembre desde las 19:00h, haremos un recorrido por las novedades que éste trae, entre ellas:

  • Xamarin.Forms 2.0,
  • Xamarin Test Recorder.
  • Mejoras en la integración con Visual Studio.
  • Y un largo etcétera.

De un modo informal, tendremos como agenda, en el mismo lugar de
siempre, repasar cuáles has sido las novedades presentadas, y poder
comentar entre nosotros qué nos parecen, ver alguna demo, experiencias,
etc.

¡Anímate, Xamarin 4 es un gran paso adelante!

Más información

[Tips and Tricks] Diccionario de recursos por plataforma en Windows 10

Introducción

Con la llegada del SDK de Windows 10 Preview tenemos la posibilidad de crear Apps Universales con un único binario
que funcione en múltiples plataformas. Es un paso importante pero que
conlleva realizar una acción que sera comun, diferenciar entre las
diferentes plataformas donde correrá dicho binario para poder adaptar la
interfaz de usuario. Con ese objetivo utilizamos entre otras opciones
los Adaptive Triggers de los que ya hemos hablado.

Sin embargo, en ocasiones la misma vista en diferentes dispositivos puede que sea totalmente diferente.

En estos casos podemos crear vistas diferentes por familias de
dispositivos. Tras añadir una vista de la forma habitual, creamos una
carpeta siguiente la siguiente nomenclatura:

  • DeviceFamily-[Family]

Donde Family es la familia del dispotivo para el que
deseamos sobrescribir la vista.Dentro de esta carpeta añadimos la vista
XAML deseada en esa plataforma.

NOTA: Añadimos la sobreescritura de la vista. Es
importante un detalle del fichero añadido, no añadimos code behind.
Esta vista utilizará el mismo code behind que la que teníamos
previamente.

Lo visto hasta ahora es genial para poder crear con facilidad vistas diferentes, pero…¿y a nivel de recursos y estilos?

Utilizando diccionarios de recursos por plataforma de dispositivos

En diccionarios de recursos, archivos XAML, organizamos los recursos y
estilos utilizados por la aplicación. Si deseamos recursos o estilos
diferentes por plataformas podemos crear diferentes elementos con
etiquetas distintas de modo que utilicemos en cada plataforma uno
diferente (utilizando Adaptive Triggers por ejemplo). El
problema de la situación anterior es que en la mayoría de casos, los
cambios son mínimos y pasamos a agrandar el conjunto de recursos
dificultando el mantenimiento de la aplicación.

¿Podemos mejorar esta situación?

Si. Podemos crear diccionarios de recursos compartidos con todo el
conjunto de recursos comunes junto a diccionarios de recursos
específicos por plataforma con estilos concretos a utilizar en las
mismas.

¿Cómo sería?

Vamos a crear un ejemplo simple donde tendremos un rectángulo
enlazado a un color. Utilizaremos un color definido en un diccionario de
recursos genérico usado en todas las plataformas. Sin embargo, en
teléfonos modificaremos el color añadiendo un diccionario de recursos
específico para teléfonos donde sobreescribiremos el color.

Comenzamos. Añadimos un diccionario de recursos llamado Colors:

<Color x:Key="AccentColor">DeepSkyBlue</Color>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource AccentColor}" />

Definimos el color a utilizar y registramos el diccionario en los recursos de la aplicación:

<Application.Resources>
     <ResourceDictionary>
          <ResourceDictionary.MergedDictionaries>
               <ResourceDictionary Source="Resources/Colors.xaml" />
          </ResourceDictionary.MergedDictionaries>
     </ResourceDictionary>
</Application.Resources>

En nuestra interfaz contaremos con un rectángulo relleno con el color definido.

<Rectangle
     Height="200"
     Width="250"
     Fill="{StaticResource AccentBrush}"/>

Hasta aquí, si ejecutamos la aplicación en cualquiera de las plataformas soportadas, el rectángulo se vera azul cielo.

A continuación, vamos a sobreescribir el color del rectángulo en
teléfonos. Creamos un nuevo diccionario de recursos de igual nombre pero
añadiendo al nombre .DeviceFamily-[Family] donde Family es la familia del dispotivo para el que deseamos sobrescribir el recurso. En nuestro ejemplo se llamará Colors.DeviceFamily-Mobile.xaml:

<Color x:Key="AccentColor">Red</Color>
<SolidColorBrush x:Key="AccentBrush" Color="{StaticResource AccentColor}" />

Definimos un nuevo color. Si ejecutamos la aplicación en Windows:

Color tomado del recurso por defecto

Color tomado del recurso por defecto

Mientras que en un teléfono:

Color tomado del recurso específico para teléfonos

Color tomado del recurso específico para teléfonos

Sencillo pero versátil, ¿cierto?.

Podéis descargar el ejemplo completo realizado a continuación:

También tenéis el código fuente disponible e GitHub:

Ver GitHub

Recordar que podéis dejar en los comentarios cualquier tipo de sugerencia o pregunta.

Más información

 

[Tips and Tricks] Windows 10: Custom State Trigger para gestionar cambios en el estado de la batería

Introducción

Entre la lista de factores importantes que marcan diferencia en practicamente cualquier dispositivo móvil encontramos la batería. Hemos ido viendo una mejora paulatina pero gradual en la calidad y duración de las mismas. Sin embargo, las exigencias requeridas también han ido incrementando. Mayor cantidad de aplicaciones usadas por los usuarios, más sensores, etc.

A pesar de las posibilidades ofrecidas por el sistema para poder gestionar el uso de la batería, reducir opciones activas cuando empieza a tener un nivel escaso, en nuestras propias aplicaciones y como desarrolladores, contamos con APIs para poder trabajar con la batería; detectar capacidad, porcentaje y otras opciones.

En este artículo, vamos a crear varios Adaptive Triggers personalizados con el objetivo de obtener información del estado y porcentaje de la batería.

¿AdaptiveTriggers?

Con la llegada del SDK de Windows 10 tenemos la posibilidad de crear Apps Universales con un único binario que funcione en múltiples plataformas. Es un paso importante pero que conlleva realizar una acción que sera comun, diferenciar entre las diferentes plataformas donde correrá dicho binario para poder adaptar la interfaz de usuario. Con ese objetivo llegan los Adaptive Triggers. Recibimos potentes novedades en los Visual States:

  • Podemos modificar propiedades sin necesidad de animaciones. Anteriormente, la síntaxis era mucho más verbosa y necesitábamos utilizar StoryBoards para cambiar cualquier propiedad por simple que fuese.
  • Contamos con los StateTrigger. Podemos lanzar Triggers cuando se aplica un estado visual sin necesidad de código adyacente en el code-behind. El concepto es muy similar a los Triggers que tenemos disponible en WPF y Silverlight y el objetivo es el mismo, realizar un cambio cuando una condición cambia.

Actualmente contamos con un tipo de StateTrigger por defecto, el Adaptive Trigger que cuenta con los siguientes tipos:

  • MinWindowWidth
  • MinWindowHeight

Ambos nos permiten detectar cambios dinámicos en el tamaño de la pantalla de modo que se adapte el tamaño de la pantalla entre pantallas pequeñas y grandes. El funcionamiento es similar a las media queries en CSS por ejemplo. Se crearán diferentes estados estableciendo unos altos y anchos mínimos, de modo que, cuando la pantalla es más grande que el tamaño asignado se activará el estado visual.

Custom State Triggers relacionados con estado de batería

Los Triggers disponibles son lo suficientemente potentes como para permitirnos un trabajo correcto adaptando la interfaz de usuario pero… ¿podemos llegar más lejos?, ¿y si no es suficiente?

Podemos crear state triggers propios creando una clase que herede de la clase base llamada StateTriggerBase disponible dentro del namespace Windows.UI.Xaml.

En esta ocasión vamos a crear dos state triggers:

  • BaterryStatusTrigger: Nos permitirá detectar el estado de la batería, es decir, si esta cargándose, descargándose, etc.
  • BatteryPercentageTrigger: Nos indicará si el nivel de la batería es alto, medio o bajo para poder actuar en consecuencia.

BatteryStatusTrigger

Comenzamos creando el primer StateTrigger. Creamos una clase que hereda de StateTriggerBase:

public class BatteryStatusTrigger : StateTriggerBase
{
 
}

Para facilitar la verificación del estado, evitando errores con cadenas vamos a crear una enumeración llamada BatteryChargingStatus:

public enum BatteryChargingStatus        
{            
     Charging = 0,
     Discharging = 1,
     Unknown = 2        
}

Y una propiedad del tipo de la enumeración que usaremos para verificar el valor actual:

private static BatteryChargingStatus _charging;

En nuestro StateTrigger crearemos una propiedad de dependencia llamada BatteryStatus que nos permitirá pasar el estado de la batería, de modo que podamos lanzar la condición idónea en cada caso:

public BatteryChargingStatus BatteryStatus
{            
     get { return (BatteryChargingStatus)GetValue(BatteryStatusProperty); }            
     set { SetValue(BatteryStatusProperty, value); }
}
         
public static readonly DependencyProperty BatteryStatusProperty =
       DependencyProperty.Register("BatteryStatus", typeof(BatteryChargingStatus), typeof(BatteryStatusTrigger),
       new PropertyMetadata(false, OnBatteryStatusPropertyChanged));
         
private static void OnBatteryStatusPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)       
{           
     var obj = (BatteryStatusTrigger)d;
     var val = (BatteryChargingStatus)e.NewValue;
 
     obj.SetActive(val == _charging);       
}

Para acceder a información relacionada con la batería utilizaremos el
namespace Windows.Devices.Power donde tendremos acceso a la clase AggregateBattery.
Esta clase agrupa todas las baterías que pueda tener el dispositivo
(podrían ser más de una) otorgando acceso a información y reportes de
forma agrupada.

Utilizamos AggregateBattery para obtener información de la batería utilizando el método GetReport que nos devolverá una instancia de tipo BatteryReport.

Accederemos a la propiedad Status (enumeración BatteryStatus) para verificar el estado de la batería:

public BatteryStatusTrigger()       
{
     UpdateStatus();
 
     Windows.Devices.Power.Battery.AggregateBattery.ReportUpdated += (s, a) =>
     {
          UpdateStatus();
     };        
}

Dependiendo del valor de Status:

  • NotPresent: No se encuentra batería.
  • Discharging: Batería descargándose.
  • Idle: Inactiva.
  • Charging: Batería cargándose.

Estableceremos el valor adecuado de nuestra propia enumeración, BatteryChargingStatus.

private void UpdateStatus()
{
     var batteryReport = Windows.Devices.Power.Battery.AggregateBattery.GetReport();
 
     switch (batteryReport.Status)
     {
          case Windows.System.Power.BatteryStatus.Charging:
               _charging = BatteryChargingStatus.Charging;
               break;
          case Windows.System.Power.BatteryStatus.Discharging:
               _charging = BatteryChargingStatus.Discharging;
               break;
          default:
               _charging = BatteryChargingStatus.Unknown;
               break;            
     }        
}

De esta forma, podemos facilmente notificar al usuario o realizar ajustes en la interfaz dependiendo del estado de la batería.

BatteryPercentageTrigger

Continuamos con el segundo de los StateTrigger. En esta ocasión nuestra intención es verificar el porcentaje de carga para poder realizar ajustes en la interfaz con facilidad dependiendo de la capacidad de batería disponible.

De nuevo, creamos una clase que hereda de StateTriggerBase:

public class BatteryPercentageTrigger : StateTriggerBase    
{
 
}

Creamos enumeración personalizada para saber el estado de la batería:

public enum BaterryPercentageState        
{            
     VeryHight = 0,
     Hight = 1,
     Medium = 2,
     Low = 3,
     Verylow = 4,
     Unknown = 5        
}

Desde valores muy elevados a muy bajos en función del nivel de batería.

private static BaterryPercentageState _batteryPercentageState;

En nuestro StateTrigger crearemos una propiedad de dependencia llamada BatteryPercentage que nos permitirá pasar el estado de carga de la batería, de modo que podamos lanzar la condición idónea en cada caso:

public BaterryPercentageState BaterryPercentage        
{            
     get { return (BaterryPercentageState)GetValue(BaterryPercentageProperty); }            
     set { SetValue(BaterryPercentageProperty, value); }        
}
         
public static readonly DependencyProperty BaterryPercentageProperty =
       DependencyProperty.Register("BaterryPercentage", typeof(BaterryPercentageState), typeof(BatteryPercentageTrigger),
       new PropertyMetadata(BaterryPercentageState.Unknown, OnBaterryPercentagePropertyChanged));
         
private static void OnBaterryPercentagePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)        
{            
     var obj = (BatteryPercentageTrigger)d;
     var val = (BaterryPercentageState)e.NewValue;
 
     obj.SetActive(val == _batteryPercentageState);        
}

Al igual que en StateTrigger anterior utilizaremos los métodos
de obtención de reportes y evento de cambio en reporte para verificar de
manera exacta el porcentaje de la batería:

public BatteryPercentageTrigger()        
{            
     UpdatePercentage();
 
     Windows.Devices.Power.Battery.AggregateBattery.ReportUpdated += (s, a) =>
     {
          UpdatePercentage();
     };        
}

Utilizaremos las propiedades FullChargeCapacityInMilliwattHours, que nos indica la capacidad de la batería junto la propiedad RemainingCapacityInMilliwattHours, que nos indica la capacidad disponible ambas en mW-h para calcular el porcentaje de la batería:

private void UpdatePercentage()        
{
     var batteryReport = Windows.Devices.Power.Battery.AggregateBattery.GetReport();
 
     if (batteryReport.FullChargeCapacityInMilliwattHours != null && batteryReport.RemainingCapacityInMilliwattHours != null)
     {
          var percentage = (batteryReport.RemainingCapacityInMilliwattHours.Value /
              (double)batteryReport.FullChargeCapacityInMilliwattHours.Value) * 100;
 
          if (percentage <= 100 && percentage > 80)
          {
              _batteryPercentageState = BaterryPercentageState.VeryHight;
          }
          else if (percentage <= 80 && percentage > 60)
          {
              _batteryPercentageState = BaterryPercentageState.Hight;
          }
          else if (percentage <= 60 && percentage > 40)
          {
              _batteryPercentageState = BaterryPercentageState.Medium;
          }
          else if (percentage <= 40 && percentage > 20)
          {
               _batteryPercentageState = BaterryPercentageState.Low;
          }
          else if (percentage <= 20 && percentage > 1)
          {
              _batteryPercentageState = BaterryPercentageState.Verylow;
          }
          else
          {
             _batteryPercentageState = BaterryPercentageState.Unknown;
          }
     }        
}  

Segun porcentaje de la batería estableceremos el valor adecuado de nuestra enumeración de tipo BatteryPercentageState.

Utilizando los StateTriggers creados

Con ambos StateTriggers a nuestro servicio ha llegado el momento de utilizarlos. Contaremos con una interfaz sumamente simple:

<TextBlock x:Name="BatteryText"               
           Text="Battery Status"/>

Mostraremos un texto diferente según el porcentaje de la batería utilizando BatteryPercentageTrigger
y el texto en color verde si el dispositivo esta cargando la batería o
rojo si al contrario, la batería se esta descargando utilizando BatteryStatusTrigger:

<VisualStateManager.VisualStateGroups>
     <VisualStateGroup>
          <VisualState x:Name="Charging">
              <VisualState.StateTriggers>
                  <customStateTriggers:BatteryStatusTrigger BatteryStatus="Charging" />
              </VisualState.StateTriggers>
              <VisualState.Setters>
                  <Setter Target="BatteryText.Foreground" Value="Green" />
              </VisualState.Setters>
          </VisualState>
          <VisualState x:Name="Discharging">
              <VisualState.StateTriggers>
                   <customStateTriggers:BatteryStatusTrigger BatteryStatus="Discharging" />
               </VisualState.StateTriggers>
               <VisualState.Setters>
                   <Setter Target="BatteryText.Foreground" Value="Red" />
               </VisualState.Setters>
           </VisualState>
       </VisualStateGroup>
       <VisualStateGroup>
           <VisualState x:Name="PercentageVeryHight">
               <VisualState.StateTriggers>
                   <customStateTriggers:BatteryPercentageTrigger BaterryPercentage="VeryHight" />
               </VisualState.StateTriggers>
               <VisualState.Setters>
                  <Setter Target="BatteryText.Text" Value="Very hight" />
               </VisualState.Setters>
          </VisualState>
          <VisualState x:Name="PercentageHight">
               <VisualState.StateTriggers>
                   <customStateTriggers:BatteryPercentageTrigger BaterryPercentage="Hight" />
               </VisualState.StateTriggers>
               <VisualState.Setters>
                   <Setter Target="BatteryText.Text" Value="Hight" />
               </VisualState.Setters>
           </VisualState>
           <VisualState x:Name="PercentageMedium">
               <VisualState.StateTriggers>
                   <customStateTriggers:BatteryPercentageTrigger BaterryPercentage="Medium" />
               </VisualState.StateTriggers>
               <VisualState.Setters>
                   <Setter Target="BatteryText.Text" Value="Medium" />
               </VisualState.Setters>
           </VisualState>
           <VisualState x:Name="PercentageLow">
               <VisualState.StateTriggers>
                   <customStateTriggers:BatteryPercentageTrigger BaterryPercentage="Low" />
               </VisualState.StateTriggers>
               <VisualState.Setters>
                   <Setter Target="BatteryText.Text" Value="Low" />
               </VisualState.Setters>
           </VisualState>
           <VisualState x:Name="PercentageVeryLow">
               <VisualState.StateTriggers>
                   <customStateTriggers:BatteryPercentageTrigger BaterryPercentage="Verylow" />
               </VisualState.StateTriggers>
               <VisualState.Setters>
                   <Setter Target="BatteryText.Text" Value="Very low" />
               </VisualState.Setters>
           </VisualState>
     </VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Si ejecutamos la App:

Custom State Triggers de batería

Custom State Triggers de batería

Nuestra aplicación se ejecuta en un dispositivo móvil con la batería
descargándose y a nivel bajo, es decir, por debajo de 40% y por encima
de 20%.

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

Ver GitHub

Recordar que cualquier tipo de duda o sugerencia la podéis dejar en los comentarios de la entrada.

Más Información