Septiembre de 2016

Volumen 31, número 9

Xamarin: productividad multiplataforma con Xamarin

Por Kevin Ashley | Septiembre de 2016

Si da un paseo por Silicon Valley estos días, observará que tanto los inversores como los desarrolladores son en su mayoría conservadores respecto a las tecnologías que utilizan. La mayoría contrataría primero a un desarrollador de iOS, seguido (si tuvieran suficiente financiación) de un desarrollador de Android o Windows. Sin embargo, este enfoque es extremadamente ineficaz y provoca varias reescrituras de código: los desarrolladores de iOS usan Objective-C, los de Android utilizan Java y los de Windows usan C#. En raras ocasiones hablan entre ellos, y mucho menos participan de un uso compartido de código, lo que provoca que no exista una coherencia entre las plataformas (y normalmente se desperdician millones de dólares para dar soporte a tecnologías y ramas de desarrollo completamente separadas). Para disponer de una estrategia de desarrollo coherente y eficaz, el uso de una tecnología multiplataforma como Xamarin resulta esencial para la productividad. Y con el aumento de las tecnologías de compilación Ahead Of Time (AOT) que traducen de forma nativa de lenguajes de alto nivel como C# a código estático para plataformas nativas, el modelo de programación en el que se necesitan desarrolladores independientes de Android, iOS y Windows están pasando a ser cosa del pasado.

Esto es un nuevo rumbo para las aplicaciones tradicionales, pero ya se ha utilizado con éxito en otras áreas, como los juegos. Por ejemplo, más de la mitad de todos los juegos en 3D para iOS, Android y Windows se desarrollan con Unity. Cuando se crean juegos en Unity, principalmente se desarrolla en C# sobre un subconjunto de Mono, lo que no es distinto de usar C# con Xamarin. Los juegos de Unity se ejecutan en más de 20 plataformas, entre las que se incluyen Windows, Android, iOS, OS X, Xbox, PlayStation y muchas otras. Es un estupendo camino que pueden tomar las aplicaciones distintas de los juegos, y Xamarin proporciona una excelente plataforma para hacerlo.

¿Se puede aplicar el mismo enfoque con otras aplicaciones, no solo con juegos? Con Xamarin, se puede: lo usé para crear Active Fitness, un conjunto de aplicaciones móviles y una plataforma de fitness basadas en la nube con más de 2 millones de usuarios de todo el mundo (activefitness.co). Comencé a usar Xamarin en fases tempranas del ciclo de desarrollo, al principio con versiones muy iniciales, y fui capaz de crear una solución multiplataforma para Windows, iOS y Android, basada en la nube de Microsoft Azure. Active Fitness, que se muestra en la Figura 1, presume de disponer de más de un 90 por ciento de código compartido entre las aplicaciones de iOS, Windows y Android. Eso de por sí ya es un aumento de productividad. Además, la mayor parte de Xamarin, incluido Xamarin.Forms (bit.ly/2a8Yo4g), es de código abierto, la plataforma disfruta de un maravilloso soporte de la comunidad y el rendimiento es idéntico al código nativo, gracias a la compatibilidad con AOT en los sistemas embebidos. Por si fuera poco, Xamarin se incluye en Visual Studio sin costo adicional, que incluye la Community Edition (gratuita).

Active Fitness en acción, con mapas en 3D y una sofisticada interfaz de usuario
Figura 1. Active Fitness en acción, con mapas en 3D y una sofisticada interfaz de usuario

Aspectos de diseño de las aplicaciones multiplataforma con Xamarin

Hace unos años, el diseño de aplicaciones móviles era sorprendentemente distinto en cada plataforma. Una aplicación de iOS, por ejemplo, no se parecía en nada a una de Android o Windows en lo que a diseño se refiere. Ya no es así. Hoy en día, la mayoría de aplicaciones modernas para Windows, iOS y Android usan paradigmas de diseño y conceptos similares. ¿Qué ocurrió? Microsoft creó el lenguaje de diseño moderno que utilizan las aplicaciones para la plataforma universal de Windows (UWP); Google ideó el diseño Material; y Apple presentó un diseño de sistema operativo de aspecto más moderno. Todos estos cambios hicieron que las aplicaciones de iOS, Android y Windows tuvieran un aspecto más parecido y actuaran de forma similar, lo que simplificó el trabajo de los desarrolladores (vea la Figura 2). Los desarrolladores incluso coincidieron a la hora de utilizar fuentes iconográficas, como Font Awesome, que usa conceptos iconográficos similares para acciones en varias plataformas. Evidentemente, las plataformas siguen teniendo diferencias visuales; por ejemplo, Windows incluye los iconos dinámicos. No obstante, quizá le sorprenda que si crea una aplicación multiplataforma, es sencillo agregarlos cuando el núcleo está ahí.

Active Fitness en Windows (izquierda), Android (centro) y iOS (derecha)
Figura 2. Active Fitness en Windows (izquierda), Android (centro) y iOS (derecha)

Cuando se desarrolla con Xamarin, existe la posibilidad de crear una interfaz de usuario atractiva para cada plataforma directamente desde dentro de Visual Studio. Esto implica el uso de Storyboards de iOS, XML de Android y XAML de Windows, con acceso a todos los controles o widgets y un enorme número de controles personalizados de los proveedores. Además, Xamarin permite un 100 por cien de acceso de API completamente en C# para cada plataforma.

Con la biblioteca Xamarin.Forms, que ofrece una abstracción de API para crear una interfaz de usuario compartida, muchos conceptos de diseño se traducen automáticamente en controles nativos para cada plataforma mediante los representadores personalizados de Xamarin, que le ofrecen la capacidad de personalizar un control multiplataforma a su representación nativa en cada plataforma. De forma que obtiene la ventaja de productividad de una aplicación realmente multiplataforma, además de posibilidades de personalización ilimitadas.

Un enorme beneficio de usar Xamarin.Forms es que se trata simplemente de un complemento, una biblioteca que se agrega al proyecto. En términos de productividad y de administración del ciclo de vida de la aplicación, tiene un valor incalculable, ya que puede crear código que no dependa mucho de los ciclos de versiones de las plataformas, que normalmente son mucho más lentos. Xamarin siempre ha tenido compatibilidad del mismo día con las versiones principales de iOS, Android y Windows, y ahora que es de código abierto, si necesita agregar un control a Xamarin.Forms, siempre puede hacerlo usted mismo mirando el código fuente o participando en el repositorio de GitHub de Xamarin.Forms. Además, Xamarin ofrece opciones de extensibilidad prácticamente ilimitadas mediante los representadores de controles personalizados. Si ya tiene una aplicación XAML, está de suerte, porque Xamarin.Forms es simplemente otro dialecto de XAML y, si la aplicación ya utiliza Silverlight, UWP o XAML, puede agregar con facilidad un complemento multiplataforma en iOS o Android.

Creación de navegación maestro-detalle con Xamarin

Echemos un vistazo a la ventaja de usar Xamarin centrándonos en un ejemplo: una aplicación típica en iOS, Android y Windows que contenga un patrón de navegación maestro-detalle (o "hamburguesa"), del repositorio de ejemplos de Xamarin de código abierto (bit.ly/29Tk9VJ). Si fuera a escribir esta aplicación como los desarrolladores tradicionales de iOS, Android y Windows, terminaría con tres proyectos separados en Objective-C, Java y C#, y tendría que disponer de controles distintos para cada uno: SplitView en Windows y patrones similares en iOS y Android. En su lugar, puede usar una única instancia de Xamarin.Forms para hacer todo el trabajo duro para todas las plataformas, como se muestra en la Figura 3.

Proyecto maestro-detalle de Xamarin destinado a Android, iOS y Windows
Figura 3. Proyecto maestro-detalle de Xamarin destinado a Android, iOS y Windows

En el archivo App.cs del proyecto portable, creo una instancia de la página raíz de la aplicación:

public App ()
{
  MainPage =
    new MasterDetailPageNavigation.
    MainPage ();
}

Tenga en cuenta que la mayoría del código del proyecto se encuentra en un proyecto portable, que se comparte entre todos los sistemas operativos, y en Xamarin.Forms puede usar XAML. El código XAML de la Figura 4 probablemente le parezca muy sencillo si está familiarizado con el control SplitView nativo de UWP.

Figura 4. Creación de una página maestro-detalle mediante XAML

<?xml version="1.0" encoding="UTF-8"?>
<MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="https://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:MasterDetailPageNavigation;assembly=MasterDetailPageNavigation"
x:Class="MasterDetailPageNavigation.MainPage">
  <MasterDetailPage.Master>
    <local:MasterPage x:Name="masterPage" />
  </MasterDetailPage.Master>
    <MasterDetailPage.Detail>
      <NavigationPage>
        <x:Arguments>
        <local:ContactsPage />
        </x:Arguments>
      </NavigationPage>
    </MasterDetailPage.Detail>
</MasterDetailPage>

Xamarin ofrece una gran flexibilidad en lo que respecta a lo que los desarrolladores pueden hacer con compilación condicional y selección de plataformas. El código siguiente cambia el icono de la página maestra si la plataforma es Windows:

if (Device.OS == TargetPlatform.Windows)
{
  Master.Icon = "hamburger.png";
}

Código específico del dispositivo y Xamarin

Por el momento todo correcto, pero ¿puedo acercarme mucho a la plataforma física de mi código Xamarin? En otras palabras, ¿puedo diferenciar el código creado para distintos tipos de dispositivos? Por suerte, Xamarin es una de las pocas tecnologías multiplataforma que admiten programación nativa y acceso a API. De forma similar a las aplicaciones para UWP que permiten diferenciar la familia de dispositivos (teléfono, tableta o escritorio), Xamarin contiene un selector Device.Idiom que resulta muy útil, como se muestra en la Figura 5.

Figura 5. Uso de Device.Idiom para seleccionar la plataforma

switch (Device.Idiom)
  {
  case TargetIdiom.Phone:
    heading.Text += " Phone ";
    break;
  case TargetIdiom.Tablet:
    heading.Text += " Tablet ";
    break;
  case TargetIdiom.Desktop:
    heading.Text += " Desktop ";
    break;
  default:
    heading.Text += " unknown ";
    break;
  }

En la Figura 6 se muestra otro selector muy útil, Device.OnPlatform, que se puede usar en el código subyacente y en XAML para ejecutar distintas acciones, en función del sistema operativo de destino.

Figura 6. Uso de Device.OnPlatform destinado a distintas plataformas

// Device.OnPlatform (Action)
//
var box = new BoxView {
  Color = Color.Green,
  WidthRequest = Device.OnPlatform (30, 40, 50),
  HorizontalOptions = LayoutOptions.Center
};
Device.OnPlatform(
  iOS: () =>{
    box.Color = box.Color.MultiplyAlpha(0.5);
    heading.TextColor = Color.Blue;
  },
  Android: () =>{
    box.Color = box.Color.AddLuminosity(0.3);
    heading.TextColor = Color.FromRgb(115, 129, 130);
  },
  WinPhone: () =>{
    box.Color = box.Color.AddLuminosity(0.3);
    heading.TextColor = Color.Accent;
  },
  Default: () =>{
    heading.Text = "what platform is this?!" + Device.OS;
  }
);

En XAML, Xamarin agrega etiquetas OnPlatform que admiten distintas plataformas, por ejemplo:

<Button Text="Start Timer"
  Clicked="TimerClicked"
  BackgroundColor="Gray"
  HorizontalOptions="Center">
  <Button.WidthRequest>
    <OnPlatform x:TypeArguments="x:Double"
      iOS="200"
      Android="300"
      WinPhone="100" />
  </Button.WidthRequest>
</Button>

Pero, ¿qué sucedería si quisiera personalizar uno de los controles que proporciona Xamarin.Forms en una plataforma nativa? Antes mencioné la característica de Xamarin conocida como representadores personalizados, que ofrece esa flexibilidad. Los representadores personalizados son clases que puede derivar de objetos integrados y ofrecen funcionalidad en implementaciones específicas de la plataforma. Digamos que quiero crear mi propio control CustomMap:

public class CustomMap : Map
  {
    public List<CustomPin> CustomPins { get; set; }
  }

En una plataforma nativa, la signatura de mi objeto incluirá lo siguiente:

[assembly:ExportRenderer (typeof(CustomMap), typeof(CustomMapRenderer))]

Por tanto, en Android, iOS y Windows, siempre puedo personalizar la apariencia y el estilo de mi control Map. Curiosamente, el contenedor del control Map de Xamarin encapsula de forma nativa el control de Mapas de Windows en Windows , el control de Google Maps en Android y el control de Mapas de iOS nativo en iOS. ¿Qué más se puede personalizar mediante representadores personalizados? Prácticamente cualquier control. El control Map es un ejemplo bastante sofisticado, pero también puede personalizar botones, etiquetas, controles deslizantes o cualquier control disponible en Xamarin.Forms.

Con Xamarin.Forms 2.2, Xamarin ahora incluye incrustación nativa, que permite agregar cualquier control nativo a una aplicación de Xamarin.Forms (bit.ly/29IEvxH).

Acceso a la nube desde Xamarin

Azure siempre ha sido compatible con características multiplataforma, con una variedad de SDK para distintas plataformas, incluidas iOS, Android, y soporte y ejemplos multiplataforma dedicados para Xamarin. Mi aplicación Active Fitness pudo escalarse hasta los 2 millones de usuarios gracias a esto. Gracias a Azure (su confiabilidad, soporte y rendimiento), los usuarios son capaces de correr, hacer jogging y realizar diversas actividades deportivas cada día con miles de dispositivos conectados cada minuto. Puede encontrar muchas guías magníficas dedicadas a Xamarin en el sitio web de Azure, que le puede ayudar a descubrir los Servicios en la nube de Microsoft más adecuados para sus aplicaciones (bit.ly/2a5kciF). Mientras tanto, me gustaría mencionar algunas áreas comunes en las que la nube es muy útil para las aplicaciones móviles:

Autenticación: si necesita autenticar o identificar usuarios, probablemente deberá usar servicios en la nube en su aplicación de Xamarin. Visite bit.ly/29HlDD3 para descubrir cómo hacerlo.

Agregar notificaciones de inserción a las aplicaciones: las notificaciones de inserción no solo ofrecen un mecanismo de comunicación para las aplicaciones, sino que también ayudan a actualizar características específicas de la plataforma, como los iconos. Puede encontrar más información en bit.ly/29HlDD3.

Sincronización sin conexión: las aplicaciones móviles de uso diario no están siempre en línea, pero los datos deben sincronizarse de forma constante, incluso si los dispositivos se desconectan del back-end. Consulte mi artículo de MSDN Magazine sobre conjuntos de datos de conexión ocasional en msdn.com/magazine/dn890372, así como una guía de inicio rápido para aplicaciones Xamarin en bit.ly/29QkXqT.

Las aplicaciones móviles de Azure son un estupendo punto inicial para la integración de muchos servicios en la nube, entre los que se incluyen el almacenamiento, las notificaciones y la autenticación. Consulte el tutorial disponible en bit.ly/29K3IHi, que está dedicado a las aplicaciones Xamarin.

Extensiones, componentes y complementos

Xamarin tuvo un gran éxito y evolucionó por medio de un número considerable de componentes, complementos y extensiones. Muchas extensiones están disponibles en GitHub o mediante NuGet. Algunas bibliotecas (por ejemplo, Android Support Libraries, las bibliotecas de cliente de Google Play Services, los SDK de Facebook y las bibliotecas de trazado de gráficas de eventos como OxyPlot) reciben el soporte de Xamarin o de su comunidad. Los complementos son ofertas únicas que permiten que los desarrolladores accedan a la funcionalidad nativa desde código compartido. Esto implica que si quiere acceder a la funcionalidad de GPS, ya no tendrá que escribir el código tres veces; simplemente descargue un paquete NuGet y acceda al GPS en el propio código compartido. Algunos complementos son de código abierto y tienen soporte de los desarrolladores. Por ejemplo, James Montemagno ha desarrollado un gran número de complementos para Xamarin, como Connectivity, Settings, Media y otros (bit.ly/2a2mM7J).

En la Figura 7 se muestran varias extensiones de utilidad que recomiendo que use a medida que profundice en el desarrollo en Xamarin.

Figura 7. Extensiones de Xamarin

Nombre Descripción Vínculo de NuGet Documentación y código fuente en GitHub
Battery Status Recopile el nivel de la batería, el estado de carga y el tipo. bit.ly/2a4gbZ6 bit.ly/2a5Ofqm
Barcode Scanner Escanee y cree códigos de barras con ZXing.NET.Mobile. bit.ly/2a5Ofqm bit.ly/29QykY9
Compass Acceda a la dirección de la brújula del dispositivo. bit.ly/2a32UAZ bit.ly/29KfcKV
Connectivity Obtenga información sobre la conectividad de red, como el tipo, y si la conexión está disponible. bit.ly/29QDplO bit.ly/2a33PBr
Cryptography PCL Crypto ofrece un conjunto portable y coherentes de API de criptografía. bit.ly/29Qz5AE bit.ly/29PzwAb
Device Info Obtenga propiedades sobre un dispositivo, como su sistema operativo, modelo, versión e identificador. bit.ly/29PzPeg bit.ly/29QzSBq
Device Motion Ofrece acceso al acelerómetro, al giroscopio, al magnetómetro y a la brújula. bit.ly/2a6SzTk bit.ly/2a35maG
Embedded Resource Desempaquete recursos incrustados para un uso multiplataforma. bit.ly/29J6Wf3 bit.ly/29J6z46
External Maps Inicie mapas externos a partir de una dirección o una combinación de latitud y longitud. bit.ly/29KgNR0 bit.ly/2abuJbI
File System PCL Storage ofrece varias API de almacenamiento multiplataforma. bit.ly/29LEOru bit.ly/28Ju1AB
Geolocator Detecte la ubicación GPS del dispositivo. bit.ly/2a70ekG bit.ly/29Tpuvd
Local Notifications Muestre notificaciones locales. bit.ly/2arOGYf bit.ly/29TpSd7
Media Haga o seleccione fotos y vídeos. bit.ly/2a6rpxi bit.ly/29TqlMm
Messaging Realice llamadas telefónicas y envíe SMS y correos electrónicos. bit.ly/2a8Uie5 bit.ly/29SEdDm
Permissions Compruebe y solicite permisos en tiempo de ejecución. bit.ly/29Tnvo8 bit.ly/29S6ZKv
Akavache key-value store Un almacén de clave y valor asincrónico y persistente (se escribe en disco). bit.ly/29Tou7I bit.ly/2arPSLf
Push Notifications Notificaciones de inserción multiplataforma para iOS y Android. bit.ly/29ToDs5 bit.ly/2aex4CR
Settings API de configuración multiplataforma sencilla y coherente. bit.ly/29ToTXT bit.ly/2a6tn0Q
Share Comparta fácilmente texto, vínculos o abra un explorador. bit.ly/2aa2R51 bit.ly/2aa3sUk
Sockets Clientes y agentes de escucha TCP y UDP, además de multidifusión UDP. bit.ly/1rQIyyR bit.ly/1y1UHPb
Text to Speech Texto a voz a partir de código compartido. bit.ly/29S7Yud bit.ly/29MMA3S
User Dialogs Habilita los diálogos de estilo cuadro de mensajes. bit.ly/2aa4dMV bit.ly/29Tqzkd
Version Tracking Realice un seguimiento de las versiones de su aplicación que un usuario ha instalado. bit.ly/29S8YhH bit.ly/2a74lNW

Por ejemplo, la comprobación de la conectividad con el complemento Connectivity en una solución multiplataforma no supone apenas esfuerzo, en comparación con el código específico de la plataforma que debe implementarse de forma separada en iOS, Android y Windows:

public static bool IsOnline
  {
    get
    {
      return Plugin.Connectivity.CrossConnectivity.Current.IsConnected;
    }
  }

Existen todavía más complementos y extensiones disponibles en bit.ly/29XZ3VM.

Compatibilidad con dispositivos: Android Wear, WatchKit y Microsoft Band

Xamarin siempre ha tenido una gran capacidad de respuesta con todo tipo de dispositivos y plataformas de dispositivos del mercado. Tuve el privilegio de trabajar con el equipo de Microsoft Band, y en el evento Build 2016 anunciamos de forma conjunta una interesantísima funcionalidad para Active Fitness que agrega compatibilidad con más de 50 actividades deportivas, entre las que se incluyen el esquí, el snowboard y muchas otras. Además, Active Fitness ahora es compatible con Android Wear, como se puede observar en la elegante esfera del reloj de la Figura 8. Si instala Active Fitness en un dispositivo Android, la esfera del reloj se admite por completo.

Esfera del reloj Android Wear con la aplicación de Active Fitness
Figura 8. Esfera del reloj Android Wear con la aplicación de Active Fitness

Con Xamarin, puede agregar aplicaciones y compatibilidad con gadgets y dispositivos así:

  • Android Wear: Xamarin incluye compatibilidad y ejemplos de código, incluida la creación de esferas de reloj en C#.
  • Apple WatchKit: para conseguir compatibilidad con Xamarin, compruebe la documentación en bit.ly/29XZ3VM.
  • Microsoft Band: además del SDK de Microsoft Band, existe un fantástico contenedor de Microsoft Band para las aplicaciones multiplataforma de Xamarin que puede encontrar en GitHub (bit.ly/29WeDli) y NuGet (bit.ly/29SOoLA).

Rendimiento y XAML compilado

Xamarin.Forms usa una combinación de XAML y lógica de código subyacente. Si lo prefiere, puede usar solamente código para crear instancias y administrar los objetos de la interfaz de usuario. De hecho, nada le impide programar la mayor parte de la interfaz de usuario, más allá de la eficiencia (la naturaleza declarativa de XAML hace que sea muy ineficiente escribir y administrar). Pero si realmente quiere hacerlo, puede derivar su elemento Page de ContentPage y escribir toda la lógica en el código, sin necesidad de XAML, como se muestra en la Figura 9.

Figura 9. Derivación de un elemento Page de ContentPage sin XAML

class ButtonCodePage : ContentPage
{
  int count = 0;
  public ButtonCodePage()
  {
    Button button = new Button
    {
      Text = String.Format("Tap for click count!")
    };
    button.Clicked += (sender, args) =>
    {
      count++;
      button.Text =
        String.Format("{0} click{1}!", count, count == 1 ? "" : "s");
    };
    this.Content = button;
  }
}

En este caso, todo el código de la interfaz de usuario es en realidad C# compilado. En el caso de XAML compilado, se usa una idea similar: puede indicar a Xamarin que compile previamente todo el XAML, lo que hace que el código de la interfaz de usuario contenido en los archivos XAML cargue y se ejecute mucho más rápido. Existen varios beneficios que aporta el XAML compilado: comprobación en tiempo de compilación inmediata, eliminación de tiempos de carga y creación de instancias, y reducción del tamaño de los archivos ejecutables. Puede habilitar la compilación de XAML a nivel de ensamblado:

[assembly: XamlCompilation(XamlCompilationOptions.Compile)]
namespace MyApp

o a nivel de clase:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class MyPage

Resumen

Mientras desarrollaba con Xamarin, he aprendido a centrarme en la productividad y a aprovechar el potencial de la comunidad de código abierto de Microsoft. Como he indicado, Xamarin responde magníficamente a las tendencias de los dispositivos y al código abierto: Android Wear, Apple Watch, Microsoft Band y las versiones más recientes de Android, iOS y Windows. Aquí figuran algunas de las nuevas incorporaciones más destacables que hacen que sea una plataforma realmente interesante:

  • Páginas de datos: simplifica el enlace de datos y consigue que las aplicaciones multipágina complejas sean aún más fáciles de crear (bit.ly/29SRtLk).
  • Kit de herramientas de aplicaciones multilingües y de localización: admite completamente los proyectos de Xamarin y agregan compatibilidad con el estándar del sector XLIFF a los proyectos (bit.ly/2a5Uzwx).
  • Incrustación de controles nativos: facilita enormemente la adición de controles nativos en Xamarin (bit.ly/29IEvxH).
  • Efectos: agrega efectos específicos de la plataforma a las aplicaciones de Xamarin (bit.ly/29RDrbD).

Xamarin ofrece una forma potente y eficaz de crear aplicaciones multiplataforma de absolutamente cualquier tipo de complejidad que funcionen en iOS, Android y Windows. Puede centrarse realmente en el contenido y la funcionalidad de la aplicación y crear una aplicación potente que funcionará en cualquier sistema operativo. Y una vez comience a crear su primera aplicación de Xamarin, pronto descubrirá una enorme y animada comunidad de desarrolladores multiplataforma.


Kevin Ashley es un arquitecto evangelizador de Microsoft. Es coautor de "Professional Windows 8 Programming" (Wrox, 2012) y programador de importantes aplicaciones y juegos, la más conocida Active Fitness (activefitness.co). A menudo presenta tecnología en diversos eventos, exhibiciones industriales y difusiones por web. Trabaja con empresas nuevas y socios, brindando asesoramiento sobre diseño de software, estrategia comercial y tecnológica, arquitectura y desarrollo. Siga su blog en kevinashley.com y su cuenta de Twitter en @kashleytwit.

Gracias a los siguientes expertos técnicos de Microsoft por revisar este artículo: James Montemagno